catlog/tt/toplevel.rs
1//! Data structures for managing toplevel declarations in the type theory.
2//!
3//! The three kinds mirror the comprehension category of `D`-models: a [Type]
4//! is a model (a context, i.e. an object of the base), a [Def] is a tight
5//! transformation (a substitution, i.e. a morphism of the base), and an
6//! [Instance] is an object of a fiber (a type in context).
7
8use derive_more::Constructor;
9
10use super::{prelude::*, stx::*, theory::*, val::*};
11use crate::zero::QualifiedName;
12
13/// A toplevel declaration.
14#[derive(Clone)]
15pub enum TopDecl {
16 /// See [Type].
17 Type(Type),
18 /// See [Def].
19 Def(Def),
20 /// See [Instance].
21 Instance(Instance),
22}
23
24/// A toplevel declaration of a type.
25///
26/// Also stores the evaluation of that type. Because this is an evaluation in
27/// the empty context, this is OK to use in any other context as well.
28#[derive(Constructor, Clone)]
29pub struct Type {
30 /// The theory for the type.
31 pub theory: Theory,
32 /// The syntax of the type (unnormalized).
33 pub stx: BaseTyS,
34 /// The value of the type (normalized).
35 pub val: BaseTyV,
36}
37
38/// A toplevel declaration of an instance of a model.
39///
40/// An instance is an object of the fiber over its codomain model `X` in the
41/// comprehension category of `D`-models: a generator/equation/sub-instance
42/// body packaged as the presentation of an `X`-instance. It is declared with
43/// `instance NAME : X := [...]`.
44///
45/// The instance is represented directly as a fiber type — a fiber
46/// [`Record`](super::stx::FiberTyS_::Record) whose fields are its
47/// generators ([`Over`](super::stx::FiberTyS_::Over)), sub-instance
48/// imports (nested records), and equations
49/// ([`Id`](super::stx::FiberTyS_::Id)). A sub-instance import `we : Edge`
50/// uses this fiber type directly.
51#[derive(Constructor, Clone)]
52pub struct Instance {
53 /// The theory that the instance is defined in.
54 pub theory: Theory,
55 /// The syntax of the instance, as a fiber record type.
56 pub stx: FiberTyS,
57 /// The value of the instance, as a fiber record type.
58 pub val: FiberTyV,
59 /// The codomain model `X` that this is an instance of.
60 pub codomain: BaseTyV,
61}
62
63/// A toplevel declaration of a term judgment.
64#[derive(Constructor, Clone)]
65pub struct Def {
66 /// The theory that the definition is defined in.
67 pub theory: Theory,
68 /// The arguments for the definition.
69 pub args: Row<BaseTyS>,
70 /// The return type of the definition (to be evaluated in an environment
71 /// with values for the arguments).
72 pub ret_ty: BaseTyS,
73 /// The body of the definition (to be evaluated in an environment with
74 /// values for the arguments).
75 pub body: BaseTmS,
76}
77
78impl TopDecl {
79 /// Unwraps the type for a toplevel-declaration of a type, or panics.
80 ///
81 /// This should only be used after type checking, when we know that a toplevel
82 /// variable name does in fact point to a toplevel declaration for a type.
83 pub fn unwrap_ty(self) -> Type {
84 match self {
85 TopDecl::Type(ty) => ty,
86 _ => panic!("top-level should be a type declaration"),
87 }
88 }
89
90 /// Unwraps the definition for a toplevel term judgment, or panics.
91 pub fn unwrap_def(self) -> Def {
92 match self {
93 TopDecl::Def(d) => d,
94 _ => panic!("top-level should be a term judgment"),
95 }
96 }
97}
98
99/// Storage for toplevel declarations.
100#[derive(Default)]
101pub struct Toplevel {
102 /// Library of theories, indexed by name.
103 pub theory_library: HashMap<QualifiedName, Theory>,
104 /// The toplevel declarations, indexed by their name.
105 pub declarations: HashMap<TopVarName, TopDecl>,
106}
107
108impl Toplevel {
109 /// Constructs an empty [Toplevel].
110 pub fn new(theory_library: HashMap<QualifiedName, Theory>) -> Self {
111 Toplevel {
112 theory_library,
113 declarations: HashMap::new(),
114 }
115 }
116
117 /// Lookup a toplevel declaration by name.
118 pub fn lookup(&self, name: TopVarName) -> Option<&TopDecl> {
119 self.declarations.get(&name)
120 }
121}