Mercurial > hg > Members > kono > Proof > agda-reflection
comparison reflection-ex.agda @ 0:776f851a03a3
reflection and tactics
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 15 Mar 2019 17:35:46 +0900 |
parents | |
children | 6f01428aaf2d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:776f851a03a3 |
---|---|
1 module reflection-ex where | |
2 | |
3 open import Data.Bool | |
4 open import Data.String | |
5 open import Data.Nat | |
6 | |
7 postulate Name : Set | |
8 {-# BUILTIN QNAME Name #-} | |
9 | |
10 primitive | |
11 primQNameEquality : Name → Name → Bool | |
12 primQNameLess : Name → Name → Bool | |
13 primShowQName : Name → String | |
14 | |
15 nameOfNat : Name | |
16 nameOfNat = quote ℕ | |
17 | |
18 isNat : Name → Bool | |
19 isNat (quote ℕ) = true | |
20 isNat _ = false | |
21 | |
22 postulate Meta : Set | |
23 {-# BUILTIN AGDAMETA Meta #-} | |
24 | |
25 primitive | |
26 primMetaEquality : Meta → Meta → Bool | |
27 primMetaLess : Meta → Meta → Bool | |
28 primShowMeta : Meta → String | |
29 | |
30 open import Data.Word | |
31 open import Data.Float | |
32 open import Data.Char | |
33 | |
34 data Literal : Set where | |
35 nat : (n : ℕ) → Literal | |
36 word64 : (n : Word64) → Literal | |
37 float : (x : Float) → Literal | |
38 char : (c : Char) → Literal | |
39 string : (s : String) → Literal | |
40 name : (x : Name) → Literal | |
41 meta : (x : Meta) → Literal | |
42 | |
43 {-# BUILTIN AGDALITERAL Literal #-} | |
44 {-# BUILTIN AGDALITNAT nat #-} | |
45 {-# BUILTIN AGDALITWORD64 word64 #-} | |
46 {-# BUILTIN AGDALITFLOAT float #-} | |
47 {-# BUILTIN AGDALITCHAR char #-} | |
48 {-# BUILTIN AGDALITSTRING string #-} | |
49 {-# BUILTIN AGDALITQNAME name #-} | |
50 {-# BUILTIN AGDALITMETA meta #-} | |
51 | |
52 data Visibility : Set where | |
53 visible hidden instance′ : Visibility | |
54 | |
55 {-# BUILTIN HIDING Visibility #-} | |
56 {-# BUILTIN VISIBLE visible #-} | |
57 {-# BUILTIN HIDDEN hidden #-} | |
58 {-# BUILTIN INSTANCE instance′ #-} | |
59 | |
60 data Relevance : Set where | |
61 relevant irrelevant : Relevance | |
62 | |
63 {-# BUILTIN RELEVANCE Relevance #-} | |
64 {-# BUILTIN RELEVANT relevant #-} | |
65 {-# BUILTIN IRRELEVANT irrelevant #-} | |
66 | |
67 data ArgInfo : Set where | |
68 arg-info : (v : Visibility) (r : Relevance) → ArgInfo | |
69 | |
70 data Arg (A : Set) : Set where | |
71 arg : (i : ArgInfo) (x : A) → Arg A | |
72 | |
73 {-# BUILTIN ARGINFO ArgInfo #-} | |
74 {-# BUILTIN ARGARGINFO arg-info #-} | |
75 {-# BUILTIN ARG Arg #-} | |
76 {-# BUILTIN ARGARG arg #-} | |
77 | |
78 | |
79 open import Data.List | |
80 | |
81 data Pattern : Set where | |
82 con : (c : Name) (ps : List (Arg Pattern)) → Pattern | |
83 dot : Pattern | |
84 var : (s : String) → Pattern | |
85 lit : (l : Literal) → Pattern | |
86 proj : (f : Name) → Pattern | |
87 absurd : Pattern | |
88 | |
89 {-# BUILTIN AGDAPATTERN Pattern #-} | |
90 {-# BUILTIN AGDAPATCON con #-} | |
91 {-# BUILTIN AGDAPATDOT dot #-} | |
92 {-# BUILTIN AGDAPATVAR var #-} | |
93 {-# BUILTIN AGDAPATLIT lit #-} | |
94 {-# BUILTIN AGDAPATPROJ proj #-} | |
95 {-# BUILTIN AGDAPATABSURD absurd #-} | |
96 | |
97 data Abs (A : Set) : Set where | |
98 abs : (s : String) (x : A) → Abs A | |
99 | |
100 {-# BUILTIN ABS Abs #-} | |
101 {-# BUILTIN ABSABS abs #-} | |
102 | |
103 data Term : Set | |
104 data Sort : Set | |
105 data Clause : Set | |
106 Type = Term | |
107 | |
108 data Term where | |
109 var : (x : ℕ) (args : List (Arg Term)) → Term | |
110 con : (c : Name) (args : List (Arg Term)) → Term | |
111 def : (f : Name) (args : List (Arg Term)) → Term | |
112 lam : (v : Visibility) (t : Abs Term) → Term | |
113 pat-lam : (cs : List Clause) (args : List (Arg Term)) → Term | |
114 pi : (a : Arg Type) (b : Abs Type) → Term | |
115 agda-sort : (s : Sort) → Term | |
116 lit : (l : Literal) → Term | |
117 meta : (x : Meta) → List (Arg Term) → Term | |
118 unknown : Term -- Treated as '_' when unquoting. | |
119 | |
120 data Sort where | |
121 set : (t : Term) → Sort -- A Set of a given (possibly neutral) level. | |
122 lit : (n : ℕ) → Sort -- A Set of a given concrete level. | |
123 unknown : Sort | |
124 | |
125 data Clause where | |
126 clause : (ps : List (Arg Pattern)) (t : Term) → Clause | |
127 absurd-clause : (ps : List (Arg Pattern)) → Clause | |
128 | |
129 {-# BUILTIN AGDASORT Sort #-} | |
130 {-# BUILTIN AGDATERM Term #-} | |
131 {-# BUILTIN AGDACLAUSE Clause #-} | |
132 | |
133 {-# BUILTIN AGDATERMVAR var #-} | |
134 {-# BUILTIN AGDATERMCON con #-} | |
135 {-# BUILTIN AGDATERMDEF def #-} | |
136 {-# BUILTIN AGDATERMMETA meta #-} | |
137 {-# BUILTIN AGDATERMLAM lam #-} | |
138 {-# BUILTIN AGDATERMEXTLAM pat-lam #-} | |
139 {-# BUILTIN AGDATERMPI pi #-} | |
140 {-# BUILTIN AGDATERMSORT agda-sort #-} | |
141 {-# BUILTIN AGDATERMLIT lit #-} | |
142 {-# BUILTIN AGDATERMUNSUPPORTED unknown #-} | |
143 | |
144 {-# BUILTIN AGDASORTSET set #-} | |
145 {-# BUILTIN AGDASORTLIT lit #-} | |
146 {-# BUILTIN AGDASORTUNSUPPORTED unknown #-} | |
147 | |
148 {-# BUILTIN AGDACLAUSECLAUSE clause #-} | |
149 {-# BUILTIN AGDACLAUSEABSURD absurd-clause #-} | |
150 | |
151 data Definition : Set where | |
152 function : (cs : List Clause) → Definition | |
153 data-type : (pars : ℕ) (cs : List Name) → Definition -- parameters and constructors | |
154 record-type : (c : Name) (fs : List (Arg Name)) → -- c: name of record constructor | |
155 Definition -- fs: fields | |
156 data-cons : (d : Name) → Definition -- d: name of data type | |
157 axiom : Definition | |
158 prim-fun : Definition | |
159 | |
160 {-# BUILTIN AGDADEFINITION Definition #-} | |
161 {-# BUILTIN AGDADEFINITIONFUNDEF function #-} | |
162 {-# BUILTIN AGDADEFINITIONDATADEF data-type #-} | |
163 {-# BUILTIN AGDADEFINITIONRECORDDEF record-type #-} | |
164 {-# BUILTIN AGDADEFINITIONDATACONSTRUCTOR data-cons #-} | |
165 {-# BUILTIN AGDADEFINITIONPOSTULATE axiom #-} | |
166 {-# BUILTIN AGDADEFINITIONPRIMITIVE prim-fun #-} | |
167 | |
168 -- Error messages can contain embedded names and terms. | |
169 data ErrorPart : Set where | |
170 strErr : String → ErrorPart | |
171 termErr : Term → ErrorPart | |
172 nameErr : Name → ErrorPart | |
173 | |
174 {-# BUILTIN AGDAERRORPART ErrorPart #-} | |
175 {-# BUILTIN AGDAERRORPARTSTRING strErr #-} | |
176 {-# BUILTIN AGDAERRORPARTTERM termErr #-} | |
177 {-# BUILTIN AGDAERRORPARTNAME nameErr #-} | |
178 | |
179 postulate | |
180 TC : ∀ {a} → Set a → Set a | |
181 returnTC : ∀ {a} {A : Set a} → A → TC A | |
182 bindTC : ∀ {a b} {A : Set a} {B : Set b} → TC A → (A → TC B) → TC B | |
183 | |
184 | |
185 {-# BUILTIN AGDATCM TC #-} | |
186 {-# BUILTIN AGDATCMRETURN returnTC #-} | |
187 {-# BUILTIN AGDATCMBIND bindTC #-} | |
188 | |
189 open import Data.Unit | |
190 open import Data.Product | |
191 | |
192 postulate | |
193 -- Unify two terms, potentially solving metavariables in the process. | |
194 unify : Term → Term → TC ⊤ | |
195 | |
196 -- Throw a type error. Can be caught by catchTC. | |
197 typeError : ∀ {a} {A : Set a} → List ErrorPart → TC A | |
198 | |
199 -- Block a type checking computation on a metavariable. This will abort | |
200 -- the computation and restart it (from the beginning) when the | |
201 -- metavariable is solved. | |
202 blockOnMeta : ∀ {a} {A : Set a} → Meta → TC A | |
203 | |
204 -- Prevent current solutions of metavariables from being rolled back in | |
205 -- case 'blockOnMeta' is called. | |
206 commitTC : TC ⊤ | |
207 | |
208 -- Backtrack and try the second argument if the first argument throws a | |
209 -- type error. | |
210 catchTC : ∀ {a} {A : Set a} → TC A → TC A → TC A | |
211 | |
212 -- Infer the type of a given term | |
213 inferType : Term → TC Type | |
214 | |
215 -- Check a term against a given type. This may resolve implicit arguments | |
216 -- in the term, so a new refined term is returned. Can be used to create | |
217 -- new metavariables: newMeta t = checkType unknown t | |
218 checkType : Term → Type → TC Term | |
219 | |
220 -- Compute the normal form of a term. | |
221 normalise : Term → TC Term | |
222 | |
223 -- Compute the weak head normal form of a term. | |
224 reduce : Term → TC Term | |
225 -- Get the current context. Returns the context in reverse order, so that | |
226 -- it is indexable by deBruijn index. Note that the types in the context are | |
227 -- valid in the rest of the context. To use in the current context they need | |
228 -- to be weakened by 1 + their position in the list. | |
229 getContext : TC (List (Arg Type)) | |
230 | |
231 -- Extend the current context with a variable of the given type. | |
232 extendContext : ∀ {a} {A : Set a} → Arg Type → TC A → TC A | |
233 | |
234 -- Set the current context. Takes a context telescope with the outer-most | |
235 -- entry first, in contrast to 'getContext'. Each type should be valid in the | |
236 -- context formed by the preceding elements in the list. | |
237 inContext : ∀ {a} {A : Set a} → List (Arg Type) → TC A → TC A | |
238 | |
239 -- Quote a value, returning the corresponding Term. | |
240 quoteTC : ∀ {a} {A : Set a} → A → TC Term | |
241 | |
242 -- Unquote a Term, returning the corresponding value. | |
243 unquoteTC : ∀ {a} {A : Set a} → Term → TC A | |
244 | |
245 -- Create a fresh name. | |
246 freshName : String → TC Name | |
247 | |
248 -- Declare a new function of the given type. The function must be defined | |
249 -- later using 'defineFun'. Takes an Arg Name to allow declaring instances | |
250 -- and irrelevant functions. The Visibility of the Arg must not be hidden. | |
251 declareDef : Arg Name → Type → TC ⊤ | |
252 | |
253 -- Declare a new postulate of the given type. The Visibility of the Arg | |
254 -- must not be hidden. It fails when executed from command-line with --safe | |
255 -- option. | |
256 declarePostulate : Arg Name → Type → TC ⊤ | |
257 | |
258 -- Define a declared function. The function may have been declared using | |
259 -- 'declareDef' or with an explicit type signature in the program. | |
260 defineFun : Name → List Clause → TC ⊤ | |
261 | |
262 -- Get the type of a defined name. Replaces 'primNameType'. | |
263 getType : Name → TC Type | |
264 | |
265 -- Get the definition of a defined name. Replaces 'primNameDefinition'. | |
266 getDefinition : Name → TC Definition | |
267 | |
268 -- Check if a name refers to a macro | |
269 isMacro : Name → TC Bool | |
270 | |
271 -- Change the behaviour of inferType, checkType, quoteTC, getContext | |
272 -- to normalise (or not) their results. The default behaviour is no | |
273 -- normalisation. | |
274 withNormalisation : ∀ {a} {A : Set a} → Bool → TC A → TC A | |
275 | |
276 -- Prints the third argument if the corresponding verbosity level is turned | |
277 -- on (with the -v flag to Agda). | |
278 debugPrint : String → ℕ → List ErrorPart → TC ⊤ | |
279 | |
280 -- Fail if the given computation gives rise to new, unsolved | |
281 -- "blocking" constraints. | |
282 noConstraints : ∀ {a} {A : Set a} → TC A → TC A | |
283 | |
284 -- Run the given TC action and return the first component. Resets to | |
285 -- the old TC state if the second component is 'false', or keep the | |
286 -- new TC state if it is 'true'. | |
287 runSpeculative : ∀ {a} {A : Set a} → TC (Σ A λ _ → Bool) → TC A | |
288 | |
289 {-# BUILTIN AGDATCMUNIFY unify #-} | |
290 {-# BUILTIN AGDATCMTYPEERROR typeError #-} | |
291 {-# BUILTIN AGDATCMBLOCKONMETA blockOnMeta #-} | |
292 {-# BUILTIN AGDATCMCATCHERROR catchTC #-} | |
293 {-# BUILTIN AGDATCMINFERTYPE inferType #-} | |
294 {-# BUILTIN AGDATCMCHECKTYPE checkType #-} | |
295 {-# BUILTIN AGDATCMNORMALISE normalise #-} | |
296 {-# BUILTIN AGDATCMREDUCE reduce #-} | |
297 {-# BUILTIN AGDATCMGETCONTEXT getContext #-} | |
298 {-# BUILTIN AGDATCMEXTENDCONTEXT extendContext #-} | |
299 {-# BUILTIN AGDATCMINCONTEXT inContext #-} | |
300 {-# BUILTIN AGDATCMQUOTETERM quoteTC #-} | |
301 {-# BUILTIN AGDATCMUNQUOTETERM unquoteTC #-} | |
302 {-# BUILTIN AGDATCMFRESHNAME freshName #-} | |
303 {-# BUILTIN AGDATCMDECLAREDEF declareDef #-} | |
304 {-# BUILTIN AGDATCMDECLAREPOSTULATE declarePostulate #-} | |
305 {-# BUILTIN AGDATCMDEFINEFUN defineFun #-} | |
306 {-# BUILTIN AGDATCMGETTYPE getType #-} | |
307 {-# BUILTIN AGDATCMGETDEFINITION getDefinition #-} | |
308 {-# BUILTIN AGDATCMCOMMIT commitTC #-} | |
309 {-# BUILTIN AGDATCMISMACRO isMacro #-} | |
310 {-# BUILTIN AGDATCMWITHNORMALISATION withNormalisation #-} | |
311 {-# BUILTIN AGDATCMDEBUGPRINT debugPrint #-} | |
312 {-# BUILTIN AGDATCMNOCONSTRAINTS noConstraints #-} | |
313 {-# BUILTIN AGDATCMRUNSPECULATIVE runSpeculative #-} | |
314 | |
315 macro | |
316 plus-to-times : Term → Term → TC ⊤ | |
317 plus-to-times (def (quote _+_) (a ∷ b ∷ [])) hole = unify hole (def (quote _*_) (a ∷ b ∷ [])) | |
318 plus-to-times v hole = unify hole v | |
319 | |
320 open import Relation.Binary.PropositionalEquality hiding ( [_] ; sym ) | |
321 | |
322 thm : (a b : ℕ) → plus-to-times (a + b) ≡ a * b | |
323 thm a b = refl | |
324 | |
325 postulate magic : Type → Term | |
326 | |
327 macro | |
328 by-magic : Term → TC ⊤ | |
329 by-magic hole = | |
330 bindTC (inferType hole) λ goal → | |
331 unify hole (magic goal) | |
332 | |
333 open import Relation.Nullary | |
334 | |
335 -- thm1 : {P NP : Set} → ¬ P ≡ NP | |
336 -- thm1 = ? by-magic | |
337 | |
338 --unquoteDecl x₁ .. x ₙ = m | |
339 --unquoteDef x₁ .. x ₙ = m | |
340 | |
341 -- Defining: id-name {A} x = x | |
342 defId : (id-name : Name) → TC ⊤ | |
343 defId id-name = do | |
344 defineFun id-name | |
345 [ clause | |
346 ( arg (arg-info hidden relevant) (var "A") | |
347 ∷ arg (arg-info visible relevant) (var "x") | |
348 ∷ [] ) | |
349 (var 0 []) | |
350 ] | |
351 | |
352 id : {A : Set} (x : A) → A | |
353 unquoteDef id = defId id | |
354 | |
355 open import Level renaming ( suc to succ ; zero to Zero ) | |
356 | |
357 mkId : (id-name : Name) → TC ⊤ | |
358 mkId id-name = | |
359 do | |
360 ty ← quoteTC ({A : Set} (x : A) → A) | |
361 declareDef (arg (arg-info visible relevant) id-name) ty | |
362 defId id-name | |
363 where | |
364 _>>=_ : {a : Level} {B A : Set a} (m : TC B) (f : (x : B) → TC A) → TC A | |
365 _>>=_ = bindTC | |
366 _>>_ : {a : Level} {B A : Set a} (m : TC B) (m' : TC A) → TC A | |
367 _>>_ x y = bindTC x ( λ _ → y ) | |
368 | |
369 | |
370 mkId' : (id-name : Name) → TC ⊤ | |
371 mkId' id-name = | |
372 bindTC | |
373 ( quoteTC ({A : Set} (x : A) → A) ) | |
374 ( λ ty → bindTC (declareDef (arg (arg-info visible relevant) id-name) ty ) | |
375 ( λ _ → defId id-name) ) | |
376 | |
377 lemma1 : ( x : Name ) → mkId x ≡ mkId' x | |
378 lemma1 x = refl | |
379 | |
380 unquoteDecl id′ = mkId id′ |