Skip to content

Commit fce58f7

Browse files
committed
Generic traversals of reflected terms (#1294)
Using it to implement weakening, strengthening and free variable check.
1 parent 7c8c17b commit fce58f7

File tree

3 files changed

+240
-0
lines changed

3 files changed

+240
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ Deprecated names
2121
New modules
2222
-----------
2323

24+
* Added `Reflection.Traversal` for generic de Bruijn-aware traversals of reflected terms.
25+
* Added `Reflection.DeBruijn` with weakening, strengthening and free variable operations
26+
on reflected terms.
27+
2428
Other major changes
2529
-------------------
2630

src/Reflection/DeBruijn.agda

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- Weakening, strengthening and free variable check for reflected terms.
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --without-K --safe #-}
8+
9+
module Reflection.DeBruijn where
10+
11+
open import Data.Bool using (Bool; true; false; _∨_; if_then_else_)
12+
open import Data.Nat as Nat using (ℕ; zero; suc; _+_; _<ᵇ_; _≡ᵇ_)
13+
open import Data.List using (List; []; _∷_; _++_)
14+
open import Data.Maybe using (Maybe; nothing; just)
15+
import Data.Maybe.Categorical as Maybe
16+
import Function.Identity.Categorical as Identity
17+
open import Category.Applicative using (RawApplicative)
18+
19+
open import Reflection
20+
open import Reflection.Argument.Visibility using (Visibility)
21+
import Reflection.Traversal as Traverse
22+
23+
private
24+
variable A : Set
25+
26+
------------------------------------------------------------------------
27+
-- Weakening
28+
29+
module _ where
30+
31+
open Traverse Identity.applicative
32+
33+
private
34+
35+
wkVar : Cxt
36+
wkVar by (from , _) i = if i <ᵇ from then i else i + by
37+
38+
actions : Actions
39+
actions k = record defaultActions { onVar = wkVar k }
40+
41+
weakenFrom′ : (Actions Cxt A A) (from by : ℕ) A A
42+
weakenFrom′ trav from by = trav (actions by) (from , []) -- not using the context part
43+
44+
weakenFrom : (from by : ℕ) Term Term
45+
weakenFrom = weakenFrom′ traverseTerm
46+
47+
weaken : (by : ℕ) Term Term
48+
weaken = weakenFrom 0
49+
50+
weakenArgs : (by : ℕ) Args Term Args Term
51+
weakenArgs = weakenFrom′ traverseArgs 0
52+
53+
weakenClauses : (by : ℕ) Clauses Clauses
54+
weakenClauses = weakenFrom′ traverseClauses 0
55+
56+
57+
------------------------------------------------------------------------
58+
-- η-expansion
59+
60+
private
61+
η : Visibility (Args Term Term) Args Term Term
62+
η h f args = lam h (abs "x" (f (weakenArgs 1 args ++ arg (arg-info h relevant) (var 0 []) ∷ [])))
63+
64+
η-expand : Visibility Term Term
65+
η-expand h (var x args) = η h (var (suc x)) args
66+
η-expand h (con c args) = η h (con c) args
67+
η-expand h (def f args) = η h (def f) args
68+
η-expand h (pat-lam cs args) = η h (pat-lam (weakenClauses 1 cs)) args
69+
η-expand h (meta x args) = η h (meta x) args
70+
η-expand h t@(lam _ _) = t
71+
η-expand h t@(pi _ _) = t
72+
η-expand h t@(agda-sort _) = t
73+
η-expand h t@(lit _) = t
74+
η-expand h t@unknown = t
75+
76+
77+
------------------------------------------------------------------------
78+
-- Strengthening
79+
80+
module _ where
81+
82+
open Traverse Maybe.applicative
83+
84+
private
85+
strVar : Cxt Maybe ℕ
86+
strVar (k , Γ) i with Nat.compare i k
87+
... | Nat.less _ _ = just i
88+
... | Nat.equal _ = nothing
89+
... | Nat.greater _ _ = just (Nat.pred i)
90+
91+
actions : Actions
92+
actions = record defaultActions { onVar = strVar }
93+
94+
strengthenFrom′ : (Actions Cxt A Maybe A) (from : ℕ) A Maybe A
95+
strengthenFrom′ trav from = trav actions (from , []) -- not using the context part
96+
97+
strengthenFrom : (from : ℕ) Term Maybe Term
98+
strengthenFrom = strengthenFrom′ traverseTerm
99+
100+
strengthen : Term Maybe Term
101+
strengthen = strengthenFrom 0
102+
103+
104+
------------------------------------------------------------------------
105+
-- Free variable check
106+
107+
module _ where
108+
109+
private
110+
anyApplicative : RawApplicative (λ _ Bool)
111+
anyApplicative .RawApplicative.pure _ = false
112+
anyApplicative .RawApplicative._⊛_ = _∨_
113+
114+
open Traverse anyApplicative
115+
116+
private
117+
fvVar : Cxt Bool
118+
fvVar i (n , _) x = i + n ≡ᵇ x
119+
120+
actions : Actions
121+
actions i = record defaultActions { onVar = fvVar i }
122+
123+
_∈FV_ : Term Bool
124+
i ∈FV t = traverseTerm (actions i) (0 , []) t

src/Reflection/Traversal.agda

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
------------------------------------------------------------------------
2+
-- The Agda standard library
3+
--
4+
-- de Bruijn-aware generic traversal of reflected terms.
5+
------------------------------------------------------------------------
6+
7+
{-# OPTIONS --without-K --safe #-}
8+
9+
open import Category.Applicative using (RawApplicative)
10+
11+
module Reflection.Traversal {F : Set Set} (AppF : RawApplicative F) where
12+
13+
open import Data.Nat using (ℕ; zero; suc; _+_)
14+
open import Data.List using (List; []; _∷_; _++_; reverse; length)
15+
open import Data.Product using (_×_; _,_)
16+
open import Data.String using (String)
17+
open import Function using (_∘_)
18+
open import Reflection
19+
20+
open RawApplicative AppF
21+
22+
------------------------------------------------------------------------
23+
-- Context representation
24+
25+
-- Track both number of variables and actual context, to avoid having to
26+
-- compute the length of the context everytime it's needed.
27+
record Cxt : Set where
28+
constructor _,_
29+
field
30+
len :
31+
context : List (String × Arg Term)
32+
33+
private
34+
_∷cxt_ : String × Arg Term Cxt Cxt
35+
e ∷cxt (n , Γ) = (suc n , e ∷ Γ)
36+
37+
_++cxt_ : List (String × Arg Term) Cxt Cxt
38+
es ++cxt (n , Γ) = (length es + n , es ++ Γ)
39+
40+
------------------------------------------------------------------------
41+
-- Actions
42+
43+
Action : Set Set
44+
Action A = Cxt A F A
45+
46+
-- A traversal gets to operate on variables, metas, and names.
47+
record Actions : Set where
48+
field
49+
onVar : Action ℕ
50+
onMeta : Action Meta
51+
onCon : Action Name
52+
onDef : Action Name
53+
54+
-- Default action: do nothing.
55+
defaultActions : Actions
56+
defaultActions .Actions.onVar _ = pure
57+
defaultActions .Actions.onMeta _ = pure
58+
defaultActions .Actions.onCon _ = pure
59+
defaultActions .Actions.onDef _ = pure
60+
61+
------------------------------------------------------------------------
62+
-- Traversal functions
63+
64+
module _ (actions : Actions) where
65+
66+
open Actions actions
67+
68+
private
69+
patternTelescope : Args Pattern List (String × Arg Term)
70+
patternTelescope [] = []
71+
patternTelescope (arg i (Pattern.var s) ∷ ps) = (s , arg i unknown) ∷ patternTelescope ps
72+
patternTelescope (arg _ (Pattern.con c ps₁) ∷ ps) = patternTelescope ps₁ ++ patternTelescope ps
73+
patternTelescope (arg i Pattern.dot ∷ ps) = patternTelescope ps
74+
patternTelescope (arg i (Pattern.lit l) ∷ ps) = patternTelescope ps
75+
patternTelescope (arg i (Pattern.proj f) ∷ ps) = patternTelescope ps
76+
patternTelescope (arg i Pattern.absurd ∷ ps) = patternTelescope ps
77+
78+
traverseTerm : Action Term
79+
traverseSort : Action Sort
80+
traverseArgs : Action (List (Arg Term))
81+
traverseArg : Action (Arg Term)
82+
traverseAbs : Arg Term Action (Abs Term)
83+
traverseClauses : Action Clauses
84+
traverseClause : Action Clause
85+
86+
traverseTerm Γ (var x args) = var <$> onVar Γ x ⊛ traverseArgs Γ args
87+
traverseTerm Γ (con c args) = con <$> onCon Γ c ⊛ traverseArgs Γ args
88+
traverseTerm Γ (def f args) = def <$> onDef Γ f ⊛ traverseArgs Γ args
89+
traverseTerm Γ (lam v t) = lam v <$> traverseAbs (arg (arg-info v relevant) unknown) Γ t
90+
traverseTerm Γ (pat-lam cs args) = pat-lam <$> traverseClauses Γ cs ⊛ traverseArgs Γ args
91+
traverseTerm Γ (pi a b) = pi <$> traverseArg Γ a ⊛ traverseAbs a Γ b
92+
traverseTerm Γ (agda-sort s) = agda-sort <$> traverseSort Γ s
93+
traverseTerm Γ (meta x args) = meta <$> onMeta Γ x ⊛ traverseArgs Γ args
94+
traverseTerm Γ t@(lit _) = pure t
95+
traverseTerm Γ t@unknown = pure t
96+
97+
traverseArg Γ (arg i t) = arg i <$> traverseTerm Γ t
98+
traverseArgs Γ [] = pure []
99+
traverseArgs Γ (a ∷ as) = _∷_ <$> traverseArg Γ a ⊛ traverseArgs Γ as
100+
101+
traverseAbs ty Γ (abs x t) = abs x <$> traverseTerm ((x , ty) ∷cxt Γ) t
102+
103+
traverseClauses Γ [] = pure []
104+
traverseClauses Γ (c ∷ cs) = _∷_ <$> traverseClause Γ c ⊛ traverseClauses Γ cs
105+
106+
traverseClause Γ (Clause.clause ps t) =
107+
Clause.clause ps <$> traverseTerm (patternTelescope ps ++cxt Γ) t
108+
traverseClause Γ c@(Clause.absurd-clause ps) = pure c
109+
110+
traverseSort Γ (Sort.set t) = Sort.set <$> traverseTerm Γ t
111+
traverseSort Γ t@(Sort.lit _) = pure t
112+
traverseSort Γ [email protected] = pure t

0 commit comments

Comments
 (0)