Skip to content

Commit

Permalink
Add indexed types (without syntax atm)
Browse files Browse the repository at this point in the history
  • Loading branch information
WhatisRT committed Jan 20, 2024
1 parent d487053 commit 91ac987
Show file tree
Hide file tree
Showing 7 changed files with 456 additions and 161 deletions.
4 changes: 2 additions & 2 deletions mced/Bootstrap/Stage-1/List.mced
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ let app := Λ X : * λ l1 : [List X] λ l2 : [List X]
[[[<<recursionList' X> [List X]> l2] λ x : X λ rec : [List X] [[<cons X> x] rec]] l1]
: ∀ X : * Π _ : [List X] Π _ : [List X] [List X].

let snoc := Λ X : * λ x : X λ xs : [List X] [[<app X> xs] [<pureList X> x]]
: ∀ X : * Π _ : X Π _ : [List X] [List X].
let snoc := Λ X : * λ xs : [List X] λ x : X [[<app X> xs] [<pureList X> x]]
: ∀ X : * Π _ : [List X] Π _ : X [List X].

let filter := Λ X : * λ f : Π _ : X Bool
[[<<recursionList' X> [List X]> <nil X>]
Expand Down
2 changes: 1 addition & 1 deletion mced/Test/Bootstrap/List.mced
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ elet pureList [X : *] (x : X) : List X := [X|x].
elet app [X : *] (l1, l2 : List X) : List X :=
l1 ?(List X) l2 (λ x : X. λ rec : List X. x ∷ rec).

elet snoc [X : *] (x : X) (xs : List X) : List X := app ?_ xs (pureList ?_ x).
elet snoc [X : *] (xs : List X) (x : X) : List X := app ?_ xs (pureList ?_ x).

elet filter [X : *] (f : X -> Bool) (l : List X) : List X :=
l ?(List X) [X|]
Expand Down
289 changes: 183 additions & 106 deletions mced/Test/Datatypes2/Define.mced

Large diffs are not rendered by default.

82 changes: 57 additions & 25 deletions mced/Test/Datatypes2/Desc.mced
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
--------------------------------------------------------------------------------

-- Currently missing:
-- - Indices
-- - Function arguments to constructors
-- - Recursion schemes
-- - Match schemes
Expand All @@ -16,21 +15,24 @@ elet TyId : * -> * := λ R : *. R.
-- Argument description

let TDesc := Term -- non-recursive
Unit -- recursive, not nested
List Term -- recursive, not nested
⊎ Term × Term. -- recursive, nested

let tdNonRec (t : Term) : TDesc := inl ?Term ?(Unit ⊎ Term × Term) t.
let tdRecNN : TDesc := inr ?Term ?(Unit ⊎ Term × Term) (inl ?Unit ?(Term × Term) tt).
let tdRecN (ts : Term × Term) : TDesc := inr ?Term ?(Unit ⊎ Term × Term) (inr ?Unit ?(Term × Term) ts).
let tdNonRec (t : Term) : TDesc := inl ?Term ?(List Term ⊎ Term × Term) t.
let tdRecNN (ts : List Term) : TDesc :=
inr ?Term ?(List Term ⊎ Term × Term) (inl ?(List Term) ?(Term × Term) ts).
let tdRecN (ts : Term × Term) : TDesc :=
inr ?Term ?(List Term ⊎ Term × Term) (inr ?(List Term) ?(Term × Term) ts).

elet TDescTy : TDesc -> Term := recursionTripleSum ?_ ?_ ?_ ?_
(λ t : Term. θ{TyConst γ{t}})
(λ _ : Unit. θ{TyId})
(λ _ : List Term. θ{TyId})
(pr1 ?Term ?Term).

-- TDescF a is a functor from indexed types (I1 -> ... -> Ik -> *) to types (*)
elet TDescF (a : TDesc) (t : Term) : Term := recursionTripleSum ?_ ?_ ?_ ?_
(λ t' : Term. t')
_ : Unit. t)
ts : List Term. appLTerm t (map ?_ ?_ mkAppU ts))
(λ ts : Term × Term. θ{γ{pr1 ?Term ?Term ts} γ{t}})
a.

Expand All @@ -39,13 +41,13 @@ elet TDescF (a : TDesc) (t : Term) : Term := recursionTripleSum ?_ ?_ ?_ ?_
elet TDescP (a : TDesc) (n : Name) (t, P, P', r : Term) : Term :=
piTerm n (TDescF a t) $ recursionTripleSum ?_ ?_ ?_ ?_
(λ _ : Term. r)
(λ _ : Unit. θ{γ{P} γ{var n} -> γ{r}})
(λ _ : List Term. θ{γ{P} γ{var n} -> γ{r}})
(λ ts : Term × Term. θ{γ{P'} γ{var n} -> γ{r}})
a.

elet TDescMono : TDesc -> Term := recursionTripleSum ?_ ?_ ?_ ?_
(λ t : Term. θ{monoConst ?γ{t}})
(λ _ : Unit. θ{monoId})
(λ _ : List Term. θ{monoId})
(pr2 ?Term ?Term).

let ADesc := Name × TDesc.
Expand All @@ -58,21 +60,26 @@ let adTDesc : ADesc -> TDesc := pr2 ?Name ?TDesc.
--------------------------------------------------------------------------------
-- Constructor description

let CDesc := Name × List ADesc.
let CDesc := Name × List ADesc × List Term.

elet CDescName (d : CDesc) : Name := pr1 ?_ ?(List ADesc) d.
elet CDescAs (d : CDesc) : List ADesc := pr2 ?_ ?(List ADesc) d.
elet CDescName (d : CDesc) : Name := pr31 ?_ ?(List ADesc) ?(List Term) d.
elet CDescAs (d : CDesc) : List ADesc := pr32 ?_ ?(List ADesc) ?(List Term) d.
elet CDescApp (d : CDesc) : List Term := pr33 ?_ ?(List ADesc) ?(List Term) d.

elet preprocessCDesc (d : CDesc) : CDesc :=
CDescName d, zipWithIndex ?_ ?_
(λ k : Nat. λ ad : ADesc. ifthenelse ?_ (emptyName (adName ad))
(φ"ctor${showNatDecimal k}", adTDesc ad)
ad)
(CDescAs d).
(CDescAs d),
CDescApp d.

--------------------------------------------------------------------------------
-- cArgTel variants: the telescope of arguments to a constructor

elet CDescApp' (t : Term) (c : CDesc) : Term :=
appLTerm t (map ?_ ?_ mkAppU (CDescApp c)).

elet cArgTelTerm (t : Term) (as : List ADesc) : Telescope :=
zipWithIndex ?_ ?_ (λ k : Nat. λ ad : ADesc.
false, adName ad, TDescF (adTDesc ad) t)
Expand All @@ -82,37 +89,51 @@ elet cArgApp (c : CDesc) : List App :=
telescopeToApp (cArgTelTerm θ{□} (CDescAs c)).

elet cArgTelName (rn : Name) (as : List ADesc) : Telescope :=
cArgTelTerm (sVarTerm rn) as.
cArgTelTerm (var rn) as.

elet cArgTel (rn : Name) (c : CDesc) : Telescope :=
cArgTelName rn (CDescAs c).

elet CDescToTy' (qn, rn : Name) (as : List ADesc) : Term :=
foldWithPi (cArgTelName rn as) (sVarTerm qn).
foldWithPi (cArgTelName rn as) (var qn).

elet CDescToTy (qn, rn : Name) (d : CDesc) : Term :=
foldWithPi (cArgTel rn d) (sVarTerm qn).
let CDescToTy (qn, rn : Name) (c : CDesc) : Term :=
foldWithPi (cArgTelTerm (var rn) (CDescAs c)) (CDescApp' (var qn) c).

--------------------------------------------------------------------------------
-- Datatype description

let Desc := Name
× Telescope -- parameters
× List Term -- indices
× List CDesc. -- constructors

elet DescName (d : Desc) : Name := pr1 ?_ ?(Telescope × List CDesc) d.
elet DescTel (d : Desc) : Telescope := pr1 ?Telescope ?(List CDesc) $ pr2 ?_ ?(Telescope × List CDesc) d.
elet DescCs (d : Desc) : List CDesc := pr2 ?Telescope ?(List CDesc) $ pr2 ?_ ?(Telescope × List CDesc) d.
elet mkDesc (n : Name) (ps : Telescope) (ixs : List Term) (cs : List CDesc) :=
(n, ps, ixs, cs).

elet DescName (d : Desc) : Name := pr1 ?_ ?(Telescope × List Term × List CDesc) d.
elet DescTel (d : Desc) : Telescope :=
pr1 ?Telescope ?(List Term × List CDesc) $ pr2 ?_ ?(Telescope × List Term × List CDesc) d.
elet DescIxs (d : Desc) : List Term := pr1 ?(List Term) ?(List CDesc) $
pr2 ?Telescope ?(List Term × List CDesc) $ pr2 ?_ ?(Telescope × List Term × List CDesc) d.
elet DescCs (d : Desc) : List CDesc := pr2 ?(List Term) ?(List CDesc) $
pr2 ?Telescope ?(List Term × List CDesc) $ pr2 ?_ ?(Telescope × List Term × List CDesc) d.

elet genDescTy (d : Desc) : Term :=
foldl ?_ ?_ (λ acc : Term. λ t : Term. θ{γ{t} -> γ{acc}}) (DescIxs d) θ{*}.

elet preprocessDesc (d : Desc) : Desc :=
DescName d, DescTel d, map ?_ ?_ preprocessCDesc (DescCs d).
DescName d, DescTel d, DescIxs d, map ?_ ?_ preprocessCDesc (DescCs d).

elet ixTel (d : Desc) : Telescope :=
zipWithIndex ?_ ?_ (λ k : Nat. λ t : Term. false, φ"k${showNatDecimal k}", t) (DescIxs d).

--------------------------------------------------------------------------------
-- genFreshD: generate a name which doesn't appear as a prefix in a Desc

elet genFreshD/adNs (ad : ADesc) : List Name := recursionTripleSum ?_ ?_ ?_ ?_
termNonFreshNames
(λ _ : Unit. [Name|])
(λ _ : List Term. [Name|])
(recursionProduct ?_ ?_ ?_ (λ t, t' : Term. app ?_ (termNonFreshNames t) (termNonFreshNames t')))
(adTDesc ad).

Expand All @@ -127,13 +148,24 @@ elet genFreshD (d : Desc) : Name -> Name :=
-- castCtor: convert a term of type F1 R -> ... -> Fn R -> X to F1 S -> ... -> Fn S -> X
-- where cn : Cast R S and the Fi come from a constructor

-- S, T: indexed, f : Indexed -> non-indexed
elet genElimMono (S, T, cast : Term) (f : Term -> Term) (monoT : Term) (t : Term) : Term :=
θ{elimCast ?γ{f S} ?γ{f T} ?(γ{monoT} ?γ{S} ?γ{T} γ{cast}) γ{t}}.

elet genElimMonoIx (S, T, cast : Term) (tel : Telescope) (f : Term -> Term) (monoT : Term) (t : Term) : Term :=
θ{elimCast ?γ{f S} ?γ{f T} ?(γ{applyTelescope θ{γ{monoT} ?γ{S} ?γ{T} γ{cast}} tel}) γ{t}}.

elet genCastTDesc (a : TDesc) (S, T, cast, t : Term) : Term := recursionTripleSum ?_ ?_ ?_ ?_
(λ _ : Term. t)
(λ ts : List Term. ψ appIxs = λ t' : Term. appLTerm t' (map ?_ ?_ mkAppU ts) : Term -> Term.
θ{elimCast ?γ{appIxs S} ?γ{appIxs T} ?γ{appIxs cast} γ{t}})
(λ ts : Term × Term. θ{□})
a.

elet CDescToCastApp (S, T, cast : Term) (c : CDesc) : List App :=
zipWith ?_ ?_ ?_
(λ p : Param. λ td : TDesc.
mkAppU $ genElimMono S T cast (TDescF td) (TDescMono td) (sVarTerm $ paramName p))
mkAppU $ genCastTDesc td S T cast (var $ paramName p))
(cArgTelTerm S (CDescAs c))
(map ?_ ?_ adTDesc (CDescAs c)).

Expand All @@ -146,7 +178,7 @@ elet castCtor (S, T, cast : Term) (t : Term) (c : CDesc) : Term :=
elet castCtorPi (S, T, cast : Term) (t : List App -> Term) (c : CDesc) : Term :=
foldWithPi (cArgTelTerm S (CDescAs c)) $ t $ CDescToCastApp S T cast c.

elet castApp (an, bn, cn : Name) (ns : List Name) (d : Desc) : List App :=
elet castApp (S, T, cast : Term) (ns : List Name) (d : Desc) : List App :=
zipWith ?_ ?_ ?_
(λ c : CDesc. λ n : Name. mkAppU $ castCtor (sVarTerm an) (sVarTerm bn) (sVarTerm cn) (sVarTerm n) c)
(λ c : CDesc. λ n : Name. mkAppU $ castCtor S T cast (var n) c)
(DescCs d) ns.
164 changes: 164 additions & 0 deletions mced/Test/Datatypes2/IHelpers.mced
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
elet genCast (X, Y : Term) (cn : Name) (ct : Term) : Term :=
θ{intrCast ?γ{X} ?γ{Y} ?γ{lambdaTerm cn X ct} ?(beta ?γ{X})}.

--------------------------------------------------------------------------------
-- Indexed Cast

elet ICastName (d : Desc) : Name := φ"${DescName d}/ICast".
elet ICastType (d : Desc) : Term := var $ ICastName d.

elet ICastLI (sn, tn : Name) (d : Desc) : LetInfo :=
mkLetInfoWithTel (ICastName d)
[Param|(false, sn, genDescTy d); (false, tn, genDescTy d)]
(foldWithPi (ixTel d)
θ{Cast γ{applyTelescope (var sn) (ixTel d)} γ{applyTelescope (var tn) (ixTel d)}})
(just ?_ θ{*}).

--------------------------------------------------------------------------------
-- Indexed Mono

elet IMonoName (d : Desc) : Name := φ"${DescName d}/IMono".
elet IMonoType (d : Desc) : Term := var $ IMonoName d.

elet IMonoLI (fn, xn, yn : Name) (d : Desc) : LetInfo :=
ψ genCast = λ t, t' : Term. θ{γ{ICastType d} γ{t} γ{t'}} : Term -> Term -> Term.
mkLetInfoWithTel (IMonoName d)
[Param|(false, fn, θ{γ{genDescTy d} -> γ{genDescTy d}})]
(forallTerm xn (genDescTy d) $ forallTerm yn (genDescTy d)
θ{γ{genCast (var xn) (var yn)} -> γ{genCast (appSingle (var fn) (var xn)) (appSingle (var fn) (var yn))}})
(just ?_ θ{*}).

--------------------------------------------------------------------------------
-- Indexed MonoD

--------------------------------------------------------------------------------
-- Indexed Rec

elet IRecName (d : Desc) : Name := φ"${DescName d}/Rec".
elet IRecType (d : Desc) : Term := var $ IRecName d.

elet IRecLI (fn, xn : Name) (d : Desc) : LetInfo :=
mkLetInfoWithTel (IRecName d)
((false, fn, θ{γ{genDescTy d} -> γ{genDescTy d}}) ∷ ixTel d)
(forallTerm xn (genDescTy d) $
forallTerm "" θ{γ{ICastType d} (γ{var fn} γ{var xn}) γ{var xn}} $
applyTelescope (var xn) (ixTel d))
(just ?_ θ{*}).

elet IRecLBName (d : Desc) : Name := φ"${DescName d}/recLB".
elet IRecLBType (d : Desc) : Term := var $ IRecLBName d.

elet IRecLBLI (cn, fn, xn, yn : Name) (d : Desc) : LetInfo :=
mkLetInfoWithTel (IRecLBName d)
[Param| (false, fn, θ{γ{genDescTy d} -> γ{genDescTy d}})
; (true, xn, (genDescTy d))
; (true, cn, θ{γ{ICastType d} (γ{var fn} γ{var xn}) γ{var xn}})]
(foldWithLambdas (ixTel d) $
genCast (applyTelescope θ{γ{IRecType d} γ{var fn}} (ixTel d))
(applyTelescope (var xn) (ixTel d)) yn θ{γ{var yn} ?γ{var xn} ?γ{(var cn)}})
(just ?_ θ{γ{ICastType d} (γ{IRecType d} γ{var fn}) γ{var xn}}).

elet IRecGLBName (d : Desc) : Name := φ"${DescName d}/recGLB".
elet IRecGLBType (d : Desc) : Term := var $ IRecGLBName d.

elet IRecGLBLI (cn, cn', fn, xn, yn, zn : Name) (d : Desc) : LetInfo :=
mkLetInfoWithTel (IRecGLBName d)
[Param| (false, fn, θ{γ{genDescTy d} -> γ{genDescTy d}})
; (true, xn, (genDescTy d))
; (true, cn, (forallTerm yn (genDescTy d) $
forallTerm "" θ{γ{ICastType d} (γ{var fn} γ{var yn}) γ{var yn}} $
θ{γ{ICastType d} γ{var xn} γ{var yn}}))]
(foldWithLambdas (ixTel d) $
genCast (applyTelescope (var xn) (ixTel d))
(applyTelescope θ{γ{IRecType d} γ{var fn}} (ixTel d))
zn $
LambdaTerm yn (genDescTy d) $ LambdaTerm cn' θ{γ{ICastType d} (γ{var fn} γ{var yn}) γ{var yn}} $
θ{elimCast ?γ{applyTelescope (var xn) (ixTel d)} ?γ{applyTelescope (var yn) (ixTel d)}
?γ{applyTelescope θ{γ{var cn} ?γ{var yn} ?γ{var cn'}} (ixTel d)} γ{var zn}})
(just ?_ θ{γ{ICastType d} γ{var xn} (γ{IRecType d} γ{var fn})}).

--------------------------------------------------------------------------------
-- roll & unroll

elet IRecRollName (d : Desc) : Name := φ"${DescName d}/recRoll".
elet IRecRollType (d : Desc) : Term := var $ IRecRollName d.

elet IRecRollLI (cn, fn, mn, xn : Name) (d : Desc) : LetInfo :=
ψ appIxTel = λ t : Term. applyTelescope t (ixTel d) : Term -> Term.
mkLetInfoWithTel (IRecRollName d)
[Param| (false, fn, θ{γ{genDescTy d} -> γ{genDescTy d}})
; (true, mn, θ{γ{IMonoType d} γ{var fn}})]
θ{γ{IRecGLBType d} γ{var fn} ?(γ{var fn} (γ{IRecType d} γ{var fn})) ?γ{
LambdaTerm xn (genDescTy d) $ LambdaTerm cn θ{γ{ICastType d} (γ{var fn} γ{var xn}) γ{var xn}} $
foldWithLambdas (ixTel d) $ θ{castTrans
?γ{appIxTel θ{γ{var fn} (γ{IRecType d} γ{var fn})}}
?γ{appIxTel θ{γ{var fn} γ{var xn}}}
?γ{appIxTel (var xn)}
?γ{appIxTel θ{γ{var mn} ?(γ{IRecType d} γ{var fn}) ?γ{var xn}
(γ{IRecLBType d} γ{var fn} ?γ{var xn} ?γ{var cn})}}
?γ{appIxTel (var cn)}}}}
(just ?_ θ{γ{ICastType d} (γ{var fn} (γ{IRecType d} γ{var fn})) (γ{IRecType d} γ{var fn})}).

elet IRollName (d : Desc) : Name := φ"${DescName d}/roll".
elet IRollType (d : Desc) : Term := var $ IRollName d.

elet elimRollLI (fn, mn, n : Name) (S, T, c : Term) (d : Desc) : LetInfo :=
ψ appIxTel = λ t : Term. applyTelescope t (ixTel d) : Term -> Term.
mkLetInfoWithTel n
((false, fn, θ{γ{genDescTy d} -> γ{genDescTy d}})
∷ (true, mn, θ{γ{IMonoType d} γ{var fn}})
∷ ixTel d)
θ{elimCast ?γ{appIxTel S} ?γ{appIxTel T} ?γ{appIxTel c}}
(just ?_ θ{γ{appIxTel S} -> γ{appIxTel T}}).

elet IRollLI (fn, mn : Name) (d : Desc) : LetInfo :=
elimRollLI fn mn (IRollName d)
θ{γ{var fn} (γ{IRecType d} γ{var fn})}
θ{γ{IRecType d} γ{var fn}}
θ{γ{IRecRollType d} γ{var fn} ?γ{var mn}}
d.

elet IRecUnrollName (d : Desc) : Name := φ"${DescName d}/recUnroll".
elet IRecUnrollType (d : Desc) : Term := var $ IRecUnrollName d.

elet IRecUnrollLI (fn, mn : Name) (d : Desc) : LetInfo :=
mkLetInfoWithTel (IRecUnrollName d)
[Param| (false, fn, θ{γ{genDescTy d} -> γ{genDescTy d}})
; (true, mn, θ{γ{IMonoType d} γ{var fn}})]
θ{γ{IRecLBType d} γ{var fn} ?(γ{var fn} (γ{IRecType d} γ{var fn}))
?(γ{var mn} ?(γ{var fn} (γ{IRecType d} γ{var fn})) ?(γ{IRecType d} γ{var fn})
(γ{IRecRollType d} γ{var fn} ?γ{var mn}))}
(just ?_ θ{γ{ICastType d} (γ{IRecType d} γ{var fn}) (γ{var fn} (γ{IRecType d} γ{var fn}))}).

elet IUnrollName (d : Desc) : Name := φ"${DescName d}/unroll".
elet IUnrollType (d : Desc) : Term := var $ IUnrollName d.

elet IUnrollLI (fn, mn : Name) (d : Desc) : LetInfo :=
elimRollLI fn mn (IUnrollName d)
θ{γ{IRecType d} γ{var fn}}
θ{γ{var fn} (γ{IRecType d} γ{var fn})}
θ{γ{IRecUnrollType d} γ{var fn} ?γ{var mn}}
d.

--------------------------------------------------------------------------------
-- Defining everything

elet DefineHelpers' (cn, cn', fn, mn, sn, tn, xn, yn, zn : Name) (d : Desc) : Eval Unit :=
defineMulti [LetInfo
| ICastLI sn tn d
; IMonoLI fn xn yn d
; IRecLI fn xn d
; IRecLBLI cn fn xn yn d
; IRecGLBLI cn cn' fn xn yn zn d
; IRecRollLI cn fn mn xn d
; IRollLI fn mn d
; IRecUnrollLI fn mn d
; IUnrollLI fn mn d
].

let DefineHelpers (d : Desc) : Eval Unit :=
ψ ns = genFreshD/ns d : List Name.
DefineHelpers' (genFreshPrefix ns "c") (genFreshPrefix ns "c'") (genFreshPrefix ns "F")
(genFreshPrefix ns "m") (genFreshPrefix ns "S") (genFreshPrefix ns "T")
(genFreshPrefix ns "X") (genFreshPrefix ns "Y") (genFreshPrefix ns "Z")
(preprocessDesc d).
Loading

0 comments on commit 91ac987

Please sign in to comment.