-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathtangled.agda
872 lines (699 loc) · 35.9 KB
/
tangled.agda
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
module tangled where
import Level as Level
open import Reflection hiding (_≟_ ; name)
open import Relation.Binary.PropositionalEquality hiding ([_])
open import Relation.Unary using (Decidable)
open import Relation.Nullary
open import Data.Unit
open import Data.Nat as Nat hiding (_⊓_)
open import Data.Bool
open import Data.Product
open import Data.List as List
open import Data.Char as Char
open import Data.String as String
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Introduction][Introduction:1]] -}
data RGB : Set where
Red Green Blue : RGB
{- Introduction:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*~NAME~%20%E2%94%80Type%20of%20known%20identifiers][~NAME~ ─Type of known identifiers:1]] -}
a-name : Name
a-name = quote ℕ
isNat : Name → Bool
isNat (quote ℕ) = true
isNat _ = false
-- bad : Set → Name
-- bad s = quote s {- s is not known -}
{- ~NAME~ ─Type of known identifiers:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*~NAME~%20%E2%94%80Type%20of%20known%20identifiers][~NAME~ ─Type of known identifiers:2]] -}
_ : showName (quote _≡_) ≡ "Agda.Builtin.Equality._≡_"
_ = refl
{- ~NAME~ ─Type of known identifiers:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*~NAME~%20%E2%94%80Type%20of%20known%20identifiers][~NAME~ ─Type of known identifiers:4]] -}
{- Like “$” but for strings. -}
_⟨𝒮⟩_ : (List Char → List Char) → String → String
f ⟨𝒮⟩ s = fromList (f (toList s))
{- This should be in the standard library; I could not locate it. -}
toDec : ∀ {ℓ} {A : Set ℓ} → (p : A → Bool) → Decidable {ℓ} {A} (λ a → p a ≡ true)
toDec p x with p x
toDec p x | false = no λ ()
toDec p x | true = yes refl
{- ~NAME~ ─Type of known identifiers:4 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*~NAME~%20%E2%94%80Type%20of%20known%20identifiers][~NAME~ ─Type of known identifiers:5]] -}
module-name : String
module-name = takeWhile (toDec (λ c → not (c Char.== '.'))) ⟨𝒮⟩ showName (quote Red)
{- ~NAME~ ─Type of known identifiers:5 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*~NAME~%20%E2%94%80Type%20of%20known%20identifiers][~NAME~ ─Type of known identifiers:7]] -}
strName : Name → String
strName n = drop (1 + String.length module-name) ⟨𝒮⟩ showName n
{- The “1 +” is for the “.” seperator in qualified names. -}
_ : strName (quote Red) ≡ "RGB.Red"
_ = refl
{- ~NAME~ ─Type of known identifiers:7 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*~Arg~%20%E2%94%80Type%20of%20arguments][~Arg~ ─Type of arguments:1]] -}
{- 𝓋isible 𝓇elevant 𝒶rgument -}
𝓋𝓇𝒶 : {A : Set} → A → Arg A
𝓋𝓇𝒶 = arg (arg-info visible relevant)
{- 𝒽idden 𝓇elevant 𝒶rgument -}
𝒽𝓇𝒶 : {A : Set} → A → Arg A
𝒽𝓇𝒶 = arg (arg-info hidden relevant)
{- ~Arg~ ─Type of arguments:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*~Arg~%20%E2%94%80Type%20of%20arguments][~Arg~ ─Type of arguments:2]] -}
{- 𝓋isible 𝓇elevant 𝓋ariable -}
𝓋𝓇𝓋 : (debruijn : ℕ) (args : List (Arg Term)) → Arg Term
𝓋𝓇𝓋 n args = arg (arg-info visible relevant) (var n args)
{- 𝒽idden 𝓇elevant 𝓋ariable -}
𝒽𝓇𝓋 : (debruijn : ℕ) (args : List (Arg Term)) → Arg Term
𝒽𝓇𝓋 n args = arg (arg-info hidden relevant) (var n args)
{- ~Arg~ ─Type of arguments:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Simple%20Types][Example: Simple Types:1]] -}
import Data.Vec as V
import Data.Fin as F
_ : quoteTerm ℕ ≡ def (quote ℕ) []
_ = refl
_ : quoteTerm V.Vec ≡ def (quote V.Vec) []
_ = refl
_ : quoteTerm (F.Fin 3) ≡ def (quote F.Fin) (𝓋𝓇𝒶 (lit (nat 3)) ∷ [])
_ = refl
{- Example: Simple Types:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Simple%20Terms][Example: Simple Terms:1]] -}
_ : quoteTerm 1 ≡ lit (nat 1)
_ = refl
_ : quoteTerm (suc zero)
≡ con (quote suc) (arg (arg-info visible relevant) (quoteTerm zero) ∷ [])
_ = refl
{- Using our helper 𝓋𝓇𝒶 -}
_ : quoteTerm (suc zero) ≡ con (quote suc) (𝓋𝓇𝒶 (quoteTerm zero) ∷ [])
_ = refl
{- Example: Simple Terms:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Simple%20Terms][Example: Simple Terms:2]] -}
_ : quoteTerm true ≡ con (quote true) []
_ = refl
_ : quoteTerm _≡_ ≡ def (quote _≡_) []
_ = refl
_ : quoteTerm ("b" ≡ "a")
≡ def (quote _≡_)
( 𝒽𝓇𝒶 (def (quote Level.zero) [])
∷ 𝒽𝓇𝒶 (def (quote String) [])
∷ 𝓋𝓇𝒶 (lit (string "b"))
∷ 𝓋𝓇𝒶 (lit (string "a")) ∷ [])
_ = refl
{- Example: Simple Terms:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Simple%20Terms][Example: Simple Terms:3]] -}
_ : ∀ {level : Level.Level}{Type : Set level} (x y : Type)
→ quoteTerm (x ≡ y)
≡ def (quote _≡_)
(𝒽𝓇𝓋 3 [] ∷ 𝒽𝓇𝓋 2 [] ∷ 𝓋𝓇𝓋 1 [] ∷ 𝓋𝓇𝓋 0 [] ∷ [])
_ = λ x y → refl
{- Example: Simple Terms:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*A%20relationship%20between%20~quote~%20and%20~quoteTerm~][A relationship between ~quote~ and ~quoteTerm~:1]] -}
postulate 𝒜 ℬ : Set
postulate 𝒻 : 𝒜 → ℬ
_ : quoteTerm 𝒻 ≡ def (quote 𝒻) []
_ = refl
{- A relationship between ~quote~ and ~quoteTerm~:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*A%20relationship%20between%20~quote~%20and%20~quoteTerm~][A relationship between ~quote~ and ~quoteTerm~:2]] -}
module _ {A B : Set} {f : A → B} where
_ : quoteTerm f ≡ var 0 []
_ = refl
{- A relationship between ~quote~ and ~quoteTerm~:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:1]] -}
_ : quoteTerm ((λ x → x) "nice") ≡ lit (string "nice")
_ = refl
{- Example: Lambda Terms:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:2]] -}
id : {A : Set} → A → A
id x = x
_ : quoteTerm (λ (x : ℕ) → id x)
≡ def (quote id) (𝒽𝓇𝒶 (def (quote ℕ) []) ∷ [])
_ = refl
{- Example: Lambda Terms:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:3]] -}
_ : quoteTerm (id "a")
≡ def (quote id)
(𝒽𝓇𝒶 (def (quote String) []) ∷ 𝓋𝓇𝒶 (lit (string "a")) ∷ [])
_ = refl
{- Example: Lambda Terms:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:4]] -}
_ : quoteTerm (λ (x : Bool) → x) ≡ lam visible (abs "x" (var 0 []))
_ = refl
{- Example: Lambda Terms:4 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:5]] -}
_ : quoteTerm (λ (a : ℕ) (f : ℕ → ℕ) → f a)
≡ lam visible (abs "a"
(lam visible (abs "f"
(var 0 (arg (arg-info visible relevant) (var 1 []) ∷ [])))))
_ = refl
{- Example: Lambda Terms:5 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:6]] -}
infixr 5 λ𝓋_↦_ λ𝒽_↦_
λ𝓋_↦_ λ𝒽_↦_ : String → Term → Term
λ𝓋 x ↦ body = lam visible (abs x body)
λ𝒽 x ↦ body = lam hidden (abs x body)
{- Example: Lambda Terms:6 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:7]] -}
_ : quoteTerm (λ (a : ℕ) (f : ℕ → ℕ) → f a)
≡ λ𝓋 "a" ↦ λ𝓋 "f" ↦ var 0 [ 𝓋𝓇𝒶 (var 1 []) ]
_ = refl
{- Example: Lambda Terms:7 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:8]] -}
_ : {A B : Set} → quoteTerm (λ (a : A) (b : B) → a)
≡ λ𝓋 "a" ↦ (λ𝓋 "b" ↦ var 1 [])
_ = refl
_ : quoteTerm (λ {A B : Set} (a : A) (_ : B) → a)
≡ (λ𝒽 "A" ↦ (λ𝒽 "B" ↦ (λ𝓋 "a" ↦ (λ𝓋 "_" ↦ var 1 []))))
_ = refl
const : {A B : Set} → A → B → A
const a _ = a
_ : quoteTerm const ≡ def (quote const) []
_ = refl
{- Example: Lambda Terms:8 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Example:%20Lambda%20Terms][Example: Lambda Terms:9]] -}
_ : quoteTerm (_≡ "b")
≡ λ𝓋 "section" ↦
(def (quote _≡_)
(𝒽𝓇𝒶 (def (quote Level.zero) []) ∷
𝒽𝓇𝒶(def (quote String) []) ∷
𝓋𝓇𝒶 (var 0 []) ∷
𝓋𝓇𝒶 (lit (string "b")) ∷ []))
_ = refl
{- Example: Lambda Terms:9 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Metaprogramming%20with%20The%20Typechecking%20Monad%20~TC~][Metaprogramming with The Typechecking Monad ~TC~:1]] -}
_>>=_ : ∀ {a b} {A : Set a} {B : Set b} → TC A → (A → TC B) → TC B
_>>=_ = bindTC
_>>_ : ∀ {a b} {A : Set a} {B : Set b} → TC A → TC B → TC B
_>>_ = λ p q → p >>= (λ _ → q)
{- Metaprogramming with The Typechecking Monad ~TC~:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Unquoting%20%E2%94%80Making%20new%20functions%20&%20types][Unquoting ─Making new functions & types:1]] -}
“ℓ₀” : Arg Term
“ℓ₀” = 𝒽𝓇𝒶 (def (quote Level.zero) [])
“RGB” : Arg Term
“RGB” = 𝒽𝓇𝒶 (def (quote RGB) [])
“Red” : Arg Term
“Red” = 𝓋𝓇𝒶 (con (quote Red) [])
{- Unquoting ─Making new functions & types:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Unquoting%20%E2%94%80Making%20new%20functions%20&%20types][Unquoting ─Making new functions & types:2]] -}
unquoteDecl IsRed =
do ty ← quoteTC (RGB → Set)
declareDef (𝓋𝓇𝒶 IsRed) ty
defineFun IsRed [ clause [ 𝓋𝓇𝒶 (var "x") ] (def (quote _≡_) (“ℓ₀” ∷ “RGB” ∷ “Red” ∷ 𝓋𝓇𝓋 0 [] ∷ [])) ]
{- Unquoting ─Making new functions & types:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Unquoting%20%E2%94%80Making%20new%20functions%20&%20types][Unquoting ─Making new functions & types:3]] -}
red-is-a-solution : IsRed Red
red-is-a-solution = refl
green-is-not-a-solution : ¬ (IsRed Green)
green-is-not-a-solution = λ ()
red-is-the-only-solution : ∀ {c} → IsRed c → c ≡ Red
red-is-the-only-solution refl = refl
{- Unquoting ─Making new functions & types:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Unquoting%20%E2%94%80Making%20new%20functions%20&%20types][Unquoting ─Making new functions & types:4]] -}
{- Definition stage, we can use ‘?’ as we form this program. -}
define-Is : Name → Name → TC ⊤
define-Is is-name qcolour = defineFun is-name
[ clause [ 𝓋𝓇𝒶 (var "x") ] (def (quote _≡_) (“ℓ₀” ∷ “RGB” ∷ 𝓋𝓇𝒶 (con qcolour []) ∷ 𝓋𝓇𝓋 0 [] ∷ [])) ]
declare-Is : Name → Name → TC ⊤
declare-Is is-name qcolour =
do let η = is-name
τ ← quoteTC (RGB → Set)
declareDef (𝓋𝓇𝒶 η) τ
defineFun is-name
[ clause [ 𝓋𝓇𝒶 (var "x") ]
(def (quote _≡_) (“ℓ₀” ∷ “RGB” ∷ 𝓋𝓇𝒶 (con qcolour []) ∷ 𝓋𝓇𝓋 0 [] ∷ [])) ]
{- Unquotation stage -}
IsRed′ : RGB → Set
unquoteDef IsRed′ = define-Is IsRed′ (quote Red)
{- Trying it out -}
_ : IsRed′ Red
_ = refl
{- Unquoting ─Making new functions & types:4 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Unquoting%20%E2%94%80Making%20new%20functions%20&%20types][Unquoting ─Making new functions & types:5]] -}
unquoteDecl IsBlue = declare-Is IsBlue (quote Blue)
unquoteDecl IsGreen = declare-Is IsGreen (quote Green)
{- Example use -}
disjoint-rgb : ∀{c} → ¬ (IsBlue c × IsGreen c)
disjoint-rgb (refl , ())
{- Unquoting ─Making new functions & types:5 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Unquoting%20%E2%94%80Making%20new%20functions%20&%20types][Unquoting ─Making new functions & types:6]] -}
unquoteDecl {- identity -}
= do {- let η = identity -}
η ← freshName "identity"
τ ← quoteTC (∀ {A : Set} → A → A)
declareDef (𝓋𝓇𝒶 η) τ
defineFun η [ clause [ 𝓋𝓇𝒶 (var "x") ] (var 0 []) ]
{- “identity” is not in scope!?
_ : ∀ {x : ℕ} → identity x ≡ x
_ = refl
-}
{- Unquoting ─Making new functions & types:6 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Unquoting%20%E2%94%80Making%20new%20functions%20&%20types][Unquoting ─Making new functions & types:7]] -}
{- Exercise: -}
unquoteDecl everywhere-0
= do let η = everywhere-0
τ ← quoteTC (ℕ → ℕ)
declareDef (𝓋𝓇𝒶 η) τ
defineFun η [ clause [ 𝓋𝓇𝒶 (var "x") ] (con (quote zero) []) ]
_ : everywhere-0 3 ≡ 0
_ = refl
{- End -}
{- Exercise: -}
unquoteDecl K
= do let η = K
τ ← quoteTC ({A B : Set} → A → B → A)
declareDef (𝓋𝓇𝒶 η) τ
defineFun η [ clause (𝓋𝓇𝒶 (var "x") ∷ 𝓋𝓇𝒶 (var "y") ∷ []) (var 1 []) ]
_ : K 3 "cat" ≡ 3
_ = refl
{- End -}
{- Exercise: -}
declare-unique : Name → (RGB → Set) → RGB → TC ⊤
declare-unique it S colour =
do let η = it
τ ← quoteTC (∀ {c} → S c → c ≡ colour)
declareDef (𝓋𝓇𝒶 η) τ
defineFun η [ clause [ 𝓋𝓇𝒶 (con (quote refl) []) ] (con (quote refl) []) ]
unquoteDecl red-unique = declare-unique red-unique IsRed Red
unquoteDecl green-unique = declare-unique green-unique IsGreen Green
unquoteDecl blue-unique = declare-unique blue-unique IsBlue Blue
_ : ∀ {c} → IsGreen c → c ≡ Green
_ = green-unique
{- End -}
{- Unquoting ─Making new functions & types:7 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Sidequest:%20Avoid%20tedious%20~refl~%20proofs][Sidequest: Avoid tedious ~refl~ proofs:1]] -}
just-Red : RGB → RGB
just-Red Red = Red
just-Red Green = Red
just-Red Blue = Red
only-Blue : RGB → RGB
only-Blue Blue = Blue
only-Blue _ = Blue
{- Sidequest: Avoid tedious ~refl~ proofs:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Sidequest:%20Avoid%20tedious%20~refl~%20proofs][Sidequest: Avoid tedious ~refl~ proofs:2]] -}
just-Red-is-constant : ∀{c} → just-Red c ≡ Red
just-Red-is-constant {Red} = refl
just-Red-is-constant {Green} = refl
just-Red-is-constant {Blue} = refl
{- Yuck, another tedious proof -}
only-Blue-is-constant : ∀{c} → only-Blue c ≡ Blue
only-Blue-is-constant {Blue} = refl
only-Blue-is-constant {Red} = refl
only-Blue-is-constant {Green} = refl
{- Sidequest: Avoid tedious ~refl~ proofs:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Sidequest:%20Avoid%20tedious%20~refl~%20proofs][Sidequest: Avoid tedious ~refl~ proofs:3]] -}
constructors : Definition → List Name
constructors (data-type pars cs) = cs
constructors _ = []
by-refls : Name → Term → TC ⊤
by-refls nom thm-you-hope-is-provable-by-refls
= let mk-cls : Name → Clause
mk-cls qcolour = clause [ 𝒽𝓇𝒶 (con qcolour []) ] (con (quote refl) [])
in
do let η = nom
δ ← getDefinition (quote RGB)
let clauses = List.map mk-cls (constructors δ)
declareDef (𝓋𝓇𝒶 η) thm-you-hope-is-provable-by-refls
defineFun η clauses
{- Sidequest: Avoid tedious ~refl~ proofs:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Sidequest:%20Avoid%20tedious%20~refl~%20proofs][Sidequest: Avoid tedious ~refl~ proofs:4]] -}
_ : ∀{c} → just-Red c ≡ Red
_ = nice
where unquoteDecl nice = by-refls nice (quoteTerm (∀{c} → just-Red c ≡ Red))
{- Sidequest: Avoid tedious ~refl~ proofs:4 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Sidequest:%20Avoid%20tedious%20~refl~%20proofs][Sidequest: Avoid tedious ~refl~ proofs:5]] -}
_ : ∀{c} → only-Blue c ≡ Blue
_ = nice
where unquoteDecl nice = by-refls nice (quoteTerm ∀{c} → only-Blue c ≡ Blue)
{- Sidequest: Avoid tedious ~refl~ proofs:5 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*C-style%20macros][C-style macros:1]] -}
luckyNum₀ : Term → TC ⊤
luckyNum₀ h = unify h (quoteTerm 55)
num₀ : ℕ
num₀ = unquote luckyNum₀
{- C-style macros:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*C-style%20macros][C-style macros:2]] -}
macro
luckyNum : Term → TC ⊤
luckyNum h = unify h (quoteTerm 55)
num : ℕ
num = luckyNum
{- C-style macros:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*C-style%20macros][C-style macros:3]] -}
{- exercise -}
macro
first : Term → TC ⊤
first goal = unify goal (var 1 [])
myconst : {A B : Set} → A → B → A
myconst = λ x → λ y → first
mysum : ( {x} y : ℕ) → ℕ
mysum y = y + first
{- end -}
{- C-style macros:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*C-style%20macros][C-style macros:4]] -}
macro
use : Term → Term → TC ⊤
use (def _ []) goal = unify goal (quoteTerm "Nice")
use v goal = unify goal (quoteTerm "WoahThere")
{- C-style macros:4 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*C-style%20macros][C-style macros:5]] -}
{- Fully defined, no arguments. -}
2+2≈4 : 2 + 2 ≡ 4
2+2≈4 = refl
_ : use 2+2≈4 ≡ "Nice"
_ = refl
{- ‘p’ has arguments. -}
_ : {x y : ℕ} {p : x ≡ y} → use p ≡ "WoahThere"
_ = refl
{- C-style macros:5 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Tedious%20Repetitive%20Proofs%20No%20More!][Tedious Repetitive Proofs No More!:1]] -}
+-rid : ∀{n} → n + 0 ≡ n
+-rid {zero} = refl
+-rid {suc n} = cong suc +-rid
*-rid : ∀{n} → n * 1 ≡ n
*-rid {zero} = refl
*-rid {suc n} = cong suc *-rid
^-rid : ∀{n} → n ^ 1 ≡ n
^-rid {zero} = refl
^-rid {suc n} = cong suc ^-rid
{- Tedious Repetitive Proofs No More!:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Tedious%20Repetitive%20Proofs%20No%20More!][Tedious Repetitive Proofs No More!:2]] -}
{- “for loops” or “Induction for ℕ” -}
foldn : (P : ℕ → Set) (base : P zero) (ind : ∀ n → P n → P (suc n))
→ ∀(n : ℕ) → P n
foldn P base ind zero = base
foldn P base ind (suc n) = ind n (foldn P base ind n)
{- Tedious Repetitive Proofs No More!:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Tedious%20Repetitive%20Proofs%20No%20More!][Tedious Repetitive Proofs No More!:3]] -}
_ : ∀ (x : ℕ) → x + 0 ≡ x
_ = foldn _ refl (λ _ → cong suc) {- This and next two are the same -}
_ : ∀ (x : ℕ) → x * 1 ≡ x
_ = foldn _ refl (λ _ → cong suc) {- Yup, same proof as previous -}
_ : ∀ (x : ℕ) → x ^ 1 ≡ x
_ = foldn _ refl (λ _ → cong suc) {- No change, same proof as previous -}
{- Tedious Repetitive Proofs No More!:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Tedious%20Repetitive%20Proofs%20No%20More!][Tedious Repetitive Proofs No More!:4]] -}
make-rid : (let A = ℕ) (_⊕_ : A → A → A) (e : A) → Name → TC ⊤
make-rid _⊕_ e nom
= do let η = nom
let clauses = clause [ 𝒽𝓇𝒶 (con (quote zero) []) ] (con (quote refl) [])
∷ clause [ 𝒽𝓇𝒶 (con (quote suc) [ 𝓋𝓇𝒶 (var "n") ]) ]
(def (quote cong) (𝓋𝓇𝒶 (quoteTerm suc) ∷ 𝓋𝓇𝒶 (def nom []) ∷ [])) ∷ []
τ ← quoteTC (∀{x : ℕ} → x ⊕ e ≡ x)
declareDef (𝓋𝓇𝒶 η) τ
defineFun η clauses
_ : ∀{x : ℕ} → x + 0 ≡ x
_ = nice where unquoteDecl nice = make-rid _+_ 0 nice
{- Tedious Repetitive Proofs No More!:4 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Tedious%20Repetitive%20Proofs%20No%20More!][Tedious Repetitive Proofs No More!:5]] -}
macro
_trivially-has-rid_ : (let A = ℕ) (_⊕_ : A → A → A) (e : A) → Term → TC ⊤
_trivially-has-rid_ _⊕_ e goal
= do τ ← quoteTC (λ(x : ℕ) → x ⊕ e ≡ x)
unify goal (def (quote foldn) {- Using foldn -}
( 𝓋𝓇𝒶 τ {- Type P -}
∷ 𝓋𝓇𝒶 (con (quote refl) []) {- Base case -}
∷ 𝓋𝓇𝒶 (λ𝓋 "_" ↦ quoteTerm (cong suc)) {- Inductive step -}
∷ []))
{- Tedious Repetitive Proofs No More!:5 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Tedious%20Repetitive%20Proofs%20No%20More!][Tedious Repetitive Proofs No More!:6]] -}
_ : ∀ (x : ℕ) → x + 0 ≡ x
_ = _+_ trivially-has-rid 0
_ : ∀ (x : ℕ) → x * 1 ≡ x
_ = _*_ trivially-has-rid 1
_ : ∀ (x : ℕ) → x * 1 ≡ x
_ = _^_ trivially-has-rid 1
{- Tedious Repetitive Proofs No More!:6 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Tedious%20Repetitive%20Proofs%20No%20More!][Tedious Repetitive Proofs No More!:7]] -}
+-rid′ : ∀{n} → n + 0 ≡ n
+-rid′ {zero} = refl
+-rid′ {suc n} = quoteGoal e in
let
suc-n : Term
suc-n = con (quote suc) [ 𝓋𝓇𝒶 (var 0 []) ]
lhs : Term
lhs = def (quote _+_) (𝓋𝓇𝒶 suc-n ∷ 𝓋𝓇𝒶 (lit (nat 0)) ∷ [])
{- Check our understanding of what the goal is “e”. -}
_ : e ≡ def (quote _≡_)
(𝒽𝓇𝒶 (quoteTerm Level.zero) ∷ 𝒽𝓇𝒶 (quoteTerm ℕ)
∷ 𝓋𝓇𝒶 lhs ∷ 𝓋𝓇𝒶 suc-n ∷ [])
_ = refl
{- What does it look normalised. -}
_ : quoteTerm (suc (n + 0) ≡ n)
≡ unquote λ goal → (do g ← normalise goal; unify g goal)
_ = refl
in
cong suc +-rid′
{- Tedious Repetitive Proofs No More!:7 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:1]] -}
≡-type-info : Term → TC (Arg Term × Arg Term × Term × Term)
≡-type-info (def (quote _≡_) (𝓁 ∷ 𝒯 ∷ arg _ l ∷ arg _ r ∷ [])) = returnTC (𝓁 , 𝒯 , l , r)
≡-type-info _ = typeError [ strErr "Term is not a ≡-type." ]
{- Our First Real Proof Tactic:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:2]] -}
{- Syntactic sugar for trying a computation, if it fails then try the other one -}
try-fun : ∀ {a} {A : Set a} → TC A → TC A → TC A
try-fun = catchTC
syntax try-fun t f = try t or-else f
{- Our First Real Proof Tactic:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:3]] -}
macro
apply₁ : Term → Term → TC ⊤
apply₁ p goal = try (do τ ← inferType p
𝓁 , 𝒯 , l , r ← ≡-type-info τ
unify goal (def (quote sym) (𝓁 ∷ 𝒯 ∷ 𝒽𝓇𝒶 l ∷ 𝒽𝓇𝒶 r ∷ 𝓋𝓇𝒶 p ∷ [])))
or-else
unify goal p
{- Our First Real Proof Tactic:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:4]] -}
postulate 𝓍 𝓎 : ℕ
postulate 𝓆 : 𝓍 + 2 ≡ 𝓎
{- Same proof yields two theorems! (งಠ_ಠ)ง -}
_ : 𝓎 ≡ 𝓍 + 2
_ = apply₁ 𝓆
_ : 𝓍 + 2 ≡ 𝓎
_ = apply₁ 𝓆
{- Our First Real Proof Tactic:4 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:5]] -}
{- Type annotation -}
syntax has A a = a ∶ A
has : ∀ (A : Set) (a : A) → A
has A a = a
{- Our First Real Proof Tactic:5 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:6]] -}
woah : {A : Set} (x y : A) → x ≡ y → (y ≡ x) × (x ≡ y)
woah x y p = apply₁ p , apply₁ p
where -- Each invocation generates a different proof, indeed:
first-pf : (apply₁ p ∶ (y ≡ x)) ≡ sym p
first-pf = refl
second-pf : (apply₁ p ∶ (x ≡ y)) ≡ p
second-pf = refl
{- Our First Real Proof Tactic:6 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:7]] -}
_ : ∀ {A : Set} {x : A} → apply₁ x ≡ x
_ = refl
_ : apply₁ "huh" ≡ "huh"
_ = refl
{- Our First Real Proof Tactic:7 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:8]] -}
macro
apply₂ : Term → Term → TC ⊤
apply₂ p goal = try unify goal (def (quote sym) (𝓋𝓇𝒶 p ∷ []))
or-else unify goal p
_ : {A : Set} (x y : A) → x ≡ y → (y ≡ x) × (x ≡ y)
_ = λ x y p → apply₂ p , apply₂ p
{- Our First Real Proof Tactic:8 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:9]] -}
macro
apply₃ : Term → Term → TC ⊤
apply₃ p goal = try unify goal (def (quote sym) (𝓋𝓇𝒶 p ∷ []))
or-else try unify goal p
or-else unify goal (con (quote refl) [])
yummah : {A : Set} {x y : A} (p : x ≡ y) → x ≡ y × y ≡ x × y ≡ y
yummah p = apply₃ p , apply₃ p , apply₃ p
{- Our First Real Proof Tactic:9 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:10]] -}
≡-type-info′ : Name → TC (Arg Term × Arg Term × Term × Term)
≡-type-info′ n = do τ ← getType n; ≡-type-info τ
macro
sumSides : Name → Term → TC ⊤
sumSides n goal = do _ , _ , l , r ← ≡-type-info′ n; unify goal (def (quote _+_) (𝓋𝓇𝒶 l ∷ 𝓋𝓇𝒶 r ∷ []))
_ : sumSides 𝓆 ≡ 𝓍 + 2 + 𝓎
_ = refl
{- Our First Real Proof Tactic:10 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Our%20First%20Real%20Proof%20Tactic][Our First Real Proof Tactic:11]] -}
macro
left : Name → Term → TC ⊤
left n goal = do _ , _ , l , r ← ≡-type-info′ n; unify goal l
right : Name → Term → TC ⊤
right n goal = do _ , _ , l , r ← ≡-type-info′ n; unify goal r
_ : sumSides 𝓆 ≡ left 𝓆 + right 𝓆
_ = refl
_ : left 𝓆 ≡ 𝓍 + 2
_ = refl
_ : right 𝓆 ≡ 𝓎
_ = refl
{- Our First Real Proof Tactic:11 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Heuristic%20for%20Writing%20a%20Macro][Heuristic for Writing a Macro:1]] -}
{- If we have “f $ args” return “f”. -}
$-head : Term → Term
$-head (var v args) = var v []
$-head (con c args) = con c []
$-head (def f args) = def f []
$-head (pat-lam cs args) = pat-lam cs []
$-head t = t
{- Heuristic for Writing a Macro:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Heuristic%20for%20Writing%20a%20Macro][Heuristic for Writing a Macro:2]] -}
postulate 𝒽 : ℕ → ℕ
postulate 𝒹 𝓮 : ℕ
postulate 𝓅𝒻 : 𝒽 𝒹 ≡ 𝓮
postulate 𝓅𝒻′ : suc 𝒹 ≡ 𝓮
macro
≡-head : Term → Term → TC ⊤
≡-head p goal = do τ ← inferType p
_ , _ , l , _ ← ≡-type-info τ
{- Could have used ‘r’ here as well. -}
unify goal ($-head l)
_ : quoteTerm (left 𝓅𝒻) ≡ def (quote 𝒽) [ 𝓋𝓇𝒶 (quoteTerm 𝒹) ]
_ = refl
_ : ≡-head 𝓅𝒻 ≡ 𝒽
_ = refl
_ : ≡-head 𝓅𝒻′ ≡ suc
_ = refl
_ : ∀ {g : ℕ → ℕ} {pf″ : g 𝒹 ≡ 𝓮} → ≡-head pf″ ≡ g
_ = refl
_ : ∀ {l r : ℕ} {g : ℕ → ℕ} {pf″ : g l ≡ r} → ≡-head pf″ ≡ g
_ = refl
_ : ∀ {l r s : ℕ} {p : l + r ≡ s} → ≡-head p ≡ _+_
_ = refl
{- Heuristic for Writing a Macro:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*Heuristic%20for%20Writing%20a%20Macro][Heuristic for Writing a Macro:3]] -}
macro
apply₄ : Term → Term → TC ⊤
apply₄ p goal = try (do τ ← inferType goal
_ , _ , l , r ← ≡-type-info τ
unify goal ((def (quote cong) (𝓋𝓇𝒶 ($-head l) ∷ 𝓋𝓇𝒶 p ∷ []))))
or-else unify goal p
_ : ∀ {x y : ℕ} {f : ℕ → ℕ} (p : x ≡ y) → f x ≡ f y
_ = λ p → apply₄ p
_ : ∀ {x y : ℕ} {f g : ℕ → ℕ} (p : x ≡ y)
→ x ≡ y
-- → f x ≡ g y {- “apply₄ p” now has a unification error ^_^ -}
_ = λ p → apply₄ p
{- Heuristic for Writing a Macro:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:1]] -}
open import Data.Nat.Properties
{- +-suc : ∀ m n → m + suc n ≡ suc (m + n) -}
test₀ : ∀ {m n k : ℕ} → k + (m + suc n) ≡ k + suc (m + n)
test₀ {m} {n} {k} = cong (k +_) (+-suc m n)
{- What about somewhere deep within a subexpression?:1 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:2]] -}
postulate 𝒳 : ℕ
postulate 𝒢 : suc 𝒳 + (𝒳 * suc 𝒳 + suc 𝒳) ≡ suc 𝒳 + suc (𝒳 * suc 𝒳 + 𝒳)
𝒮𝒳 : Arg Term
𝒮𝒳 = 𝓋𝓇𝒶 (con (quote suc) [ 𝓋𝓇𝒶 (quoteTerm 𝒳) ])
𝒢ˡ 𝒢ʳ : Term
𝒢ˡ = def (quote _+_) (𝒮𝒳 ∷ 𝓋𝓇𝒶 (def (quote _+_) (𝓋𝓇𝒶 (def (quote _*_) (𝓋𝓇𝒶 (quoteTerm 𝒳) ∷ 𝒮𝒳 ∷ [])) ∷ 𝒮𝒳 ∷ [])) ∷ [])
𝒢ʳ = def (quote _+_) (𝒮𝒳 ∷ 𝓋𝓇𝒶 (con (quote suc) [ 𝓋𝓇𝒶 (def (quote _+_) (𝓋𝓇𝒶 (def (quote _*_) (𝓋𝓇𝒶 (quoteTerm 𝒳) ∷ 𝒮𝒳 ∷ [])) ∷ 𝓋𝓇𝒶 (quoteTerm 𝒳) ∷ [])) ]) ∷ [])
{- What about somewhere deep within a subexpression?:2 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:3]] -}
{- Should definitily be in the standard library -}
⌊_⌋ : ∀ {a} {A : Set a} → Dec A → Bool
⌊ yes p ⌋ = true
⌊ no ¬p ⌋ = false
import Agda.Builtin.Reflection as Builtin
_$-≟_ : Term → Term → Bool
con c args $-≟ con c′ args′ = Builtin.primQNameEquality c c′
def f args $-≟ def f′ args′ = Builtin.primQNameEquality f f′
var x args $-≟ var x′ args′ = ⌊ x Nat.≟ x′ ⌋
_ $-≟ _ = false
{- Only gets heads and as much common args, not anywhere deep. :'( -}
infix 5 _⊓_
{-# TERMINATING #-} {- Fix this by adding fuel (con c args) ≔ 1 + length args -}
_⊓_ : Term → Term → Term
l ⊓ r with l $-≟ r | l | r
...| false | x | y = unknown
...| true | var f args | var f′ args′ = var f (List.zipWith (λ{ (arg i!! t) (arg j!! s) → arg i!! (t ⊓ s) }) args args′)
...| true | con f args | con f′ args′ = con f (List.zipWith (λ{ (arg i!! t) (arg j!! s) → arg i!! (t ⊓ s) }) args args′)
...| true | def f args | def f′ args′ = def f (List.zipWith (λ{ (arg i!! t) (arg j!! s) → arg i!! (t ⊓ s) }) args args′)
...| true | ll | _ = ll {- Left biased; using ‘unknown’ does not ensure idempotence. -}
{- What about somewhere deep within a subexpression?:3 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:4]] -}
_ : 𝒢ˡ ⊓ 𝒢ʳ ≡ def (quote _+_) (𝒮𝒳 ∷ 𝓋𝓇𝒶 unknown ∷ [])
_ = refl
{- test using argument function 𝒶 and argument number X -}
_ : {X : ℕ} {𝒶 : ℕ → ℕ}
→
let gl = quoteTerm (𝒶 X + (X * 𝒶 X + 𝒶 X))
gr = quoteTerm (𝒶 X + 𝒶 (X * 𝒶 X + X))
in gl ⊓ gr ≡ def (quote _+_) (𝓋𝓇𝒶 (var 0 [ 𝓋𝓇𝒶 (var 1 []) ]) ∷ 𝓋𝓇𝒶 unknown ∷ [])
_ = refl
{- What about somewhere deep within a subexpression?:4 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:5]] -}
{- ‘unknown’ goes to a variable, a De Bruijn index -}
unknown-elim : ℕ → List (Arg Term) → List (Arg Term)
unknown-elim n [] = []
unknown-elim n (arg i unknown ∷ xs) = arg i (var n []) ∷ unknown-elim (n + 1) xs
unknown-elim n (arg i (var x args) ∷ xs) = arg i (var (n + suc x) args) ∷ unknown-elim n xs
unknown-elim n (arg i x ∷ xs) = arg i x ∷ unknown-elim n xs
{- Essentially we want: body(unknownᵢ) ⇒ λ _ → body(var 0)
However, now all “var 0” references in “body” refer to the wrong argument;
they now refer to “one more lambda away than before”. -}
unknown-count : List (Arg Term) → ℕ
unknown-count [] = 0
unknown-count (arg i unknown ∷ xs) = 1 + unknown-count xs
unknown-count (arg i _ ∷ xs) = unknown-count xs
unknown-λ : ℕ → Term → Term
unknown-λ zero body = body
unknown-λ (suc n) body = unknown-λ n (λ𝓋 "section" ↦ body)
{- Replace ‘unknown’ with sections -}
patch : Term → Term
patch it@(def f args) = unknown-λ (unknown-count args) (def f (unknown-elim 0 args))
patch it@(var f args) = unknown-λ (unknown-count args) (var f (unknown-elim 0 args))
patch it@(con f args) = unknown-λ (unknown-count args) (con f (unknown-elim 0 args))
patch t = t
{- What about somewhere deep within a subexpression?:5 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:6]] -}
macro
spine : Term → Term → TC ⊤
spine p goal
= do τ ← inferType p
_ , _ , l , r ← ≡-type-info τ
unify goal (patch (l ⊓ r))
{- What about somewhere deep within a subexpression?:6 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:7]] -}
_ : spine 𝒢 ≡ suc 𝒳 +_
_ = refl
module testing-postulated-functions where
postulate 𝒶 : ℕ → ℕ
postulate _𝒷_ : ℕ → ℕ → ℕ
postulate 𝓰 : 𝒶 𝒳 𝒷 𝒳 ≡ 𝒶 𝒳 𝒷 𝒶 𝓍
_ : spine 𝓰 ≡ (𝒶 𝒳 𝒷_)
_ = refl
_ : {X : ℕ} {G : suc X + (X * suc X + suc X) ≡ suc X + suc (X * suc X + X)}
→ quoteTerm G ≡ var 0 []
_ = refl
{- What about somewhere deep within a subexpression?:7 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:8]] -}
_ : spine 𝓅𝒻 ≡ 𝒽
_ = refl
_ : spine 𝓅𝒻′ ≡ suc
_ = refl
_ : ∀ {g : ℕ → ℕ} {pf″ : g 𝒹 ≡ 𝓮} → spine pf″ ≡ g
_ = refl
_ : ∀ {l r : ℕ} {g : ℕ → ℕ} {pf″ : g l ≡ r} → spine pf″ ≡ g
_ = refl
_ : ∀ {l r s : ℕ} {p : l + r ≡ s} → spine p ≡ _+_
_ = refl
{- What about somewhere deep within a subexpression?:8 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:9]] -}
macro
apply₅ : Term → Term → TC ⊤
apply₅ p hole
= do τ ← inferType hole
_ , _ , l , r ← ≡-type-info τ
unify hole ((def (quote cong)
(𝓋𝓇𝒶 (patch (l ⊓ r)) ∷ 𝓋𝓇𝒶 p ∷ [])))
{- What about somewhere deep within a subexpression?:9 ends here -}
{- [[file:~/reflection/gentle-intro-to-reflection.lagda::*What%20about%20somewhere%20deep%20within%20a%20subexpression?][What about somewhere deep within a subexpression?:10]] -}
_ : suc 𝒳 + (𝒳 * suc 𝒳 + suc 𝒳) ≡ suc 𝒳 + suc (𝒳 * suc 𝒳 + 𝒳)
_ = apply₅ (+-suc (𝒳 * suc 𝒳) 𝒳)
test : ∀ {m n k : ℕ} → k + (m + suc n) ≡ k + suc (m + n)
test {m} {n} {k} = apply₅ (+-suc m n)
{- What about somewhere deep within a subexpression?:10 ends here -}