Skip to content

Commit 9c56155

Browse files
authored
Generic traversals of reflected terms (#1294)
Using it to implement weakening, strengthening and free variable check.
1 parent cfbc578 commit 9c56155

File tree

3 files changed

+254
-0
lines changed

3 files changed

+254
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ Deprecated names
5252
New modules
5353
-----------
5454

55+
* Added `Reflection.Traversal` for generic de Bruijn-aware traversals of reflected terms.
56+
* Added `Reflection.DeBruijn` with weakening, strengthening and free variable operations
57+
on reflected terms.
58+
5559
Other major changes
5660
-------------------
5761

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: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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+
pattern
30+
field
31+
len :
32+
context : List (String × Arg Term)
33+
34+
private
35+
_∷cxt_ : String × Arg Term Cxt Cxt
36+
e ∷cxt (n , Γ) = (suc n , e ∷ Γ)
37+
38+
_++cxt_ : List (String × Arg Term) Cxt Cxt
39+
es ++cxt (n , Γ) = (length es + n , es ++ Γ)
40+
41+
------------------------------------------------------------------------
42+
-- Actions
43+
44+
Action : Set Set
45+
Action A = Cxt A F A
46+
47+
-- A traversal gets to operate on variables, metas, and names.
48+
record Actions : Set where
49+
field
50+
onVar : Action ℕ
51+
onMeta : Action Meta
52+
onCon : Action Name
53+
onDef : Action Name
54+
55+
-- Default action: do nothing.
56+
defaultActions : Actions
57+
defaultActions .Actions.onVar _ = pure
58+
defaultActions .Actions.onMeta _ = pure
59+
defaultActions .Actions.onCon _ = pure
60+
defaultActions .Actions.onDef _ = pure
61+
62+
------------------------------------------------------------------------
63+
-- Traversal functions
64+
65+
module _ (actions : Actions) where
66+
67+
open Actions actions
68+
69+
traverseTerm : Action Term
70+
traverseSort : Action Sort
71+
traversePattern : Action Pattern
72+
traverseArgs : Action (List (Arg Term))
73+
traverseArg : Action (Arg Term)
74+
traversePats : Action (List (Arg Pattern))
75+
traverseAbs : Arg Term Action (Abs Term)
76+
traverseClauses : Action Clauses
77+
traverseClause : Action Clause
78+
traverseTel : Action (List (String × Arg Term))
79+
80+
traverseTerm Γ (var x args) = var <$> onVar Γ x ⊛ traverseArgs Γ args
81+
traverseTerm Γ (con c args) = con <$> onCon Γ c ⊛ traverseArgs Γ args
82+
traverseTerm Γ (def f args) = def <$> onDef Γ f ⊛ traverseArgs Γ args
83+
traverseTerm Γ (lam v t) = lam v <$> traverseAbs (arg (arg-info v relevant) unknown) Γ t
84+
traverseTerm Γ (pat-lam cs args) = pat-lam <$> traverseClauses Γ cs ⊛ traverseArgs Γ args
85+
traverseTerm Γ (pi a b) = pi <$> traverseArg Γ a ⊛ traverseAbs a Γ b
86+
traverseTerm Γ (agda-sort s) = agda-sort <$> traverseSort Γ s
87+
traverseTerm Γ (meta x args) = meta <$> onMeta Γ x ⊛ traverseArgs Γ args
88+
traverseTerm Γ t@(lit _) = pure t
89+
traverseTerm Γ t@unknown = pure t
90+
91+
traverseArg Γ (arg i t) = arg i <$> traverseTerm Γ t
92+
traverseArgs Γ [] = pure []
93+
traverseArgs Γ (a ∷ as) = _∷_ <$> traverseArg Γ a ⊛ traverseArgs Γ as
94+
95+
traverseAbs ty Γ (abs x t) = abs x <$> traverseTerm ((x , ty) ∷cxt Γ) t
96+
97+
traverseClauses Γ [] = pure []
98+
traverseClauses Γ (c ∷ cs) = _∷_ <$> traverseClause Γ c ⊛ traverseClauses Γ cs
99+
100+
traverseClause Γ (Clause.clause tel ps t) =
101+
Clause.clause <$> traverseTel Γ tel
102+
⊛ traversePats Γ′ ps
103+
⊛ traverseTerm Γ′ t
104+
where Γ′ = reverse tel ++cxt Γ
105+
traverseClause Γ (Clause.absurd-clause tel ps) =
106+
Clause.absurd-clause <$> traverseTel Γ tel
107+
⊛ traversePats Γ′ ps
108+
where Γ′ = reverse tel ++cxt Γ
109+
110+
traverseTel Γ [] = pure []
111+
traverseTel Γ ((x , ty) ∷ tel) =
112+
_∷_ ∘ (x ,_) <$> traverseArg Γ ty ⊛ traverseTel ((x , ty) ∷cxt Γ) tel
113+
114+
traverseSort Γ (Sort.set t) = Sort.set <$> traverseTerm Γ t
115+
traverseSort Γ t@(Sort.lit _) = pure t
116+
traverseSort Γ [email protected] = pure t
117+
118+
traversePattern Γ (Pattern.con c ps) = Pattern.con <$> onCon Γ c ⊛ traversePats Γ ps
119+
traversePattern Γ (Pattern.dot t) = Pattern.dot <$> traverseTerm Γ t
120+
traversePattern Γ (Pattern.var x) = Pattern.var <$> onVar Γ x
121+
traversePattern Γ p@(Pattern.lit _) = pure p
122+
traversePattern Γ p@(Pattern.proj _) = pure p
123+
traversePattern Γ [email protected] = pure p
124+
125+
traversePats Γ [] = pure []
126+
traversePats Γ (arg i p ∷ ps) = _∷_ ∘ arg i <$> traversePattern Γ p ⊛ traversePats Γ ps

0 commit comments

Comments
 (0)