-
Notifications
You must be signed in to change notification settings - Fork 33
/
grammar.rkt
156 lines (135 loc) · 5.9 KB
/
grammar.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#lang racket
(require redex/reduction-semantics racket/set)
(provide formality-logic
RootUniverse
)
(define-language formality-logic
;; The "hook" is a bit of a hack that allows the environment
;; to (on demand) get access to clauses and invariants from the
;; program without actually knowing the full representation
;; of the program itself. See hook.rkt for more details.
(Hook ::= (Hook: any))
;; Parameters to the logic:
(Parameter ::= Term) ; Value of a variable
(ParameterKind ::= Term) ; Kinds for variables (e.g., type/lifetimes)
(Predicate ::= Term) ; Kinds of predicates we can prove
(VarInequality ::= Term) ; Variable relationships inferred and stored in the environment
(InequalityOp ::= Term) ; Relations between terms beyond `==`
;; Env: Typing environment
;;
;; * Hook -- the "hook" that lets us get program information
;; * Universe -- the largest universe yet defined
;; * VarBinders -- maps variable names to quantifier-kinds/universes
;; * When bound variables are instantiated, their names
;; are added to this list.
;; * When equating (existential) variables,
;; we modify the universe that it is mapped to here
;; * Hypotheses -- facts believed to be true, introduced by
;; where clauses
(Envs ::= (Env ...))
(Env ::= (Hook Universe VarBinders Substitution VarInequalities Hypotheses))
;; Maps variables to their values; those values are not core to the
;; logic, though.
(Substitution ::= ((VarId Parameter) ...))
(Substitution-or-error ::= Substitution Error)
;; VarBinder -- maps a `VarId` to a kind (ty/lifetime/etc), quantifier kind (forall/exists),
;; and universe
(VarBinders ::= (VarBinder ...))
(VarBinder ::= (VarId ParameterKind Quantifier Universe))
;; VarInequality -- for variables that don't have a known
;; value (which would appear in the substitution), we may
;; have an *inequality*. These are opaque to the logic layer,
;; they get manipulated by the type layer in the various
;; hook functions.
(VarInequalities ::= (VarInequality ...))
;; KindedVarId: declares a bound parameter and
;; its kind (type, lifetime, etc).
(KindedVarIds ::= (KindedVarId ...))
(KindedVarId ::= (ParameterKind VarId))
;; `Parameters` -- parameters
(Parameters ::= (Parameter ...))
;; `Predicate` -- the atomic items that we can prove
(Predicates ::= (Predicate ...))
;; ANCHOR:GoalsAndHypotheses
;; `Goal` -- things we can prove. These consists of predicates
;; joined by various forms of logical operators that are built
;; into the proving system (see `cosld-solve.rkt`).
;;
;; `AtomicGoal` -- goals whose meaning is defined by the
;; upper layers and is opaque to this layer. We break them into
;; two categories, predicates and relations, which affects how
;; the upper layers convey their meaning to us:
;;
;; * For *predicates* the upper layer gives us a set of `Clause`
;; instances we can use to prove them true.
;;
;; * For *relations* the upper layer directly manipulates the
;; environment using a callback function and gives us a set of
;; subsequent goals. This is used for things like subtyping that use a
;; very custom search strategy to avoid getting "lost in the solver" and to implement
;; inference.
;;
;; `BuiltinGoal` -- defines logical connectives that the solver layer
;; directly manages.
(Goals = (Goal ...))
(Goal ::= AtomicGoal BuiltinGoal)
(AtomicGoal ::=
Predicate
Relation)
(BuiltinGoal ::=
(All Goals)
(Any Goals)
(Implies Hypotheses Goal)
(Quantifier KindedVarIds Goal)
)
;; `Clause`, `Hypothesis` -- axioms. These are both built-in and derived from
;; user-defined items like `trait` and `impl`.
(Hypotheses Clauses ::= (Clause ...))
(Hypothesis Clause ::=
AtomicGoal
(Implies Goals AtomicGoal)
(ForAll KindedVarIds Clause)
)
;; ANCHOR_END:GoalsAndHypotheses
;; A `FlatHypothesis` is a flattened form of hypotheses; it is equally expressive
;; with the recursive structure. Useful for matching.
(FlatHypotheses ::= (FlatHypothesis ...))
(FlatHypothesis ::= (ForAll KindedVarIds FlatImplicationHypothesis))
(FlatImplicationHypotheses ::= (FlatImplicationHypothesis ...))
(FlatImplicationHypothesis ::= (Implies Goals AtomicGoal))
;; `Invariants` -- things which must be true or the type system has some bugs.
;; A rather restricted form of clause.
(Invariants ::= (Invariant ...))
(Invariant ::= (ForAll KindedVarIds (Implies (Predicate) Predicate)))
;; Different ways to relate parameters
(Relations ::= (Relation ...))
(Relation ::= (Parameter RelationOp Parameter))
(RelationOp ::= == InequalityOp)
;; `Quantifier` -- the two kinds of quantifiers.
(Quantifier ::= ForAll Exists)
;; `Universe` -- the root universe `RootUniverse` consists of all user-defined names.
;; Each time we enter into a `ForAll` quantifier, we introduce a new universe
;; that extends the previous one to add new names that didn't exist in the old
;; universe (e.g., the placeholders for the universally quantified variables).
;; See the paper XXX
(Universe ::= (UniverseId number))
;; Identifiers -- these are all equivalent, but we give them fresh names to help
;; clarify their purpose
(VarIds ::= (VarId ...))
(VarId AnyId ::= variable-not-otherwise-mentioned)
; Term -- preferred name to any that reads better :)
(Terms ::= (Term ...))
(Term ::= any)
(TermPair ::= (Term Term))
(TermPairs ::= (TermPair ...))
; Internal data structure used during cosld proving
(Prove/Stacks ::= (Predicates Predicates))
(Prove/Coinductive ::= + -)
#:binding-forms
(ForAll ((ParameterKind VarId) ...) any #:refers-to (shadow VarId ...))
(Exists ((ParameterKind VarId) ...) any #:refers-to (shadow VarId ...))
)
(define-term
RootUniverse
(UniverseId 0)
)