summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--soat.ipkg1
-rw-r--r--src/Data/Morphism/Indexed.idr8
-rw-r--r--src/Data/Setoid/Indexed.idr7
-rw-r--r--src/Soat/FirstOrder/Algebra.idr8
-rw-r--r--src/Soat/FirstOrder/Algebra/Coproduct.idr118
-rw-r--r--src/Soat/FirstOrder/Algebra/FreeExtension.idr58
-rw-r--r--src/Soat/FirstOrder/Term.idr118
-rw-r--r--src/Soat/SecondOrder/Algebra.idr26
-rw-r--r--src/Soat/SecondOrder/Algebra/Lift.idr553
9 files changed, 583 insertions, 314 deletions
diff --git a/soat.ipkg b/soat.ipkg
index d5cdcd9..a34b8c2 100644
--- a/soat.ipkg
+++ b/soat.ipkg
@@ -10,6 +10,7 @@ modules = Data.Morphism.Indexed
, Soat.Data.Sublist
, Soat.FirstOrder.Algebra
, Soat.FirstOrder.Algebra.Coproduct
+ , Soat.FirstOrder.Algebra.FreeExtension
, Soat.FirstOrder.Signature
, Soat.FirstOrder.Term
, Soat.SecondOrder.Algebra
diff --git a/src/Data/Morphism/Indexed.idr b/src/Data/Morphism/Indexed.idr
index c271c90..6737275 100644
--- a/src/Data/Morphism/Indexed.idr
+++ b/src/Data/Morphism/Indexed.idr
@@ -11,3 +11,11 @@ record IFunction {a : Type} (x, y : ISetoid a) where
constructor MkIFunction
func : IFunc x.U y.U
cong : (i : a) -> {u, v : x.U i} -> x.relation i u v -> y.relation i (func i u) (func i v)
+
+public export
+ifunc : IFunc x y -> IFunction (isetoid x) (isetoid y)
+ifunc f = MkIFunction f (\i => cong (f i))
+
+public export
+compFunc : IFunction b c -> IFunction a b -> IFunction a c
+compFunc f g = MkIFunction (\i => f.func i . g.func i) (\i => f.cong i . g.cong i)
diff --git a/src/Data/Setoid/Indexed.idr b/src/Data/Setoid/Indexed.idr
index 7277932..db5fb07 100644
--- a/src/Data/Setoid/Indexed.idr
+++ b/src/Data/Setoid/Indexed.idr
@@ -40,5 +40,12 @@ public export
(.index) x i = MkSetoid (x.U i) (x.relation i) (x.equivalence i)
public export
+(.reindex) : ISetoid b -> (f : a -> b) -> ISetoid a
+(.reindex) x f = MkISetoid
+ (\i => x.U $ f i)
+ (\i => x.relation $ f i)
+ (\i => x.equivalence $ f i)
+
+public export
isetoid : (a -> Type) -> ISetoid a
isetoid u = MkISetoid u (\_ => Equal) (\_ => equiv)
diff --git a/src/Soat/FirstOrder/Algebra.idr b/src/Soat/FirstOrder/Algebra.idr
index 245af6d..26370cc 100644
--- a/src/Soat/FirstOrder/Algebra.idr
+++ b/src/Soat/FirstOrder/Algebra.idr
@@ -104,3 +104,11 @@ compIsHomo fHomo gHomo = MkIsHomomorphism
public export
compHomo : {a, b, c : Algebra sig} -> Homomorphism b c -> Homomorphism a b -> Homomorphism a c
compHomo f g = MkHomomorphism _ $ compIsHomo f.homo g.homo
+
+public export
+record Isomorphism {0 sig : Signature} (a, b : Algebra sig) where
+ constructor MkIsomorphism
+ to : Homomorphism a b
+ from : Homomorphism b a
+ fromTo : {t : sig.T} -> (x : a.raw.U t) -> a.relation t (from.func t $ to.func t x) x
+ toFrom : {t : sig.T} -> (x : b.raw.U t) -> b.relation t (to.func t $ from.func t x) x
diff --git a/src/Soat/FirstOrder/Algebra/Coproduct.idr b/src/Soat/FirstOrder/Algebra/Coproduct.idr
index d0b1b14..a29080f 100644
--- a/src/Soat/FirstOrder/Algebra/Coproduct.idr
+++ b/src/Soat/FirstOrder/Algebra/Coproduct.idr
@@ -73,14 +73,13 @@ Coproduct x y = MakeRawAlgebra
}
public export
-CoproductIsAlgebra : IsAlgebra sig x rel -> IsAlgebra sig y rel'
- -> IsAlgebra sig (Coproduct x y)
- ((~=~) (MkRawAlgebraWithRelation x rel) (MkRawAlgebraWithRelation y rel'))
-CoproductIsAlgebra xIsAlgebra yIsAlgebra = MkIsAlgebra
+CoproductIsAlgebra : (x, y : Algebra sig)
+ -> IsAlgebra sig (Coproduct x.raw y.raw) ((~=~) x.rawWithRelation y.rawWithRelation)
+CoproductIsAlgebra x y = MkIsAlgebra
{ equivalence = \t => MkEquivalence
{ refl = MkReflexive $ coprodRelRefl
- (\t => (xIsAlgebra.equivalence t).refl)
- (\t => (yIsAlgebra.equivalence t).refl)
+ (\t => (x.algebra.equivalence t).refl)
+ (\t => (y.algebra.equivalence t).refl)
_
, sym = MkSymmetric $ Sym
, trans = MkTransitive $ Trans
@@ -90,44 +89,88 @@ CoproductIsAlgebra xIsAlgebra yIsAlgebra = MkIsAlgebra
public export
CoproductAlgebra : (x, y : Algebra sig) -> Algebra sig
-CoproductAlgebra x y = MkAlgebra _ _ $ CoproductIsAlgebra x.algebra y.algebra
-
-public export
-injectLIsHomo : IsHomomorphism x (CoproductAlgebra x y) (\_ => Done . Left)
-injectLIsHomo = MkIsHomomorphism
- { cong = \_ => DoneL
- , semHomo = InjectL
- }
-
-public export
-injectRIsHomo : IsHomomorphism y (CoproductAlgebra x y) (\_ => Done . Right)
-injectRIsHomo = MkIsHomomorphism
- { cong = \_ => DoneR
- , semHomo = InjectR
- }
+CoproductAlgebra x y = MkAlgebra _ _ $ CoproductIsAlgebra x y
public export
injectLHomo : Homomorphism x (CoproductAlgebra x y)
-injectLHomo = MkHomomorphism _ $ injectLIsHomo
+injectLHomo = MkHomomorphism _ $ MkIsHomomorphism { cong = \_ => DoneL , semHomo = InjectL }
public export
injectRHomo : Homomorphism y (CoproductAlgebra x y)
-injectRHomo = MkHomomorphism _ $ injectRIsHomo
+injectRHomo = MkHomomorphism _ $ MkIsHomomorphism { cong = \_ => DoneR , semHomo = InjectR }
public export
coproduct : {z : RawAlgebra sig} -> IFunc x z.U -> IFunc y z.U -> IFunc (CoproductSet sig x y) z.U
-coproduct f g _ = bindTerm (\i => either (f i) (g i))
+coproduct f g = bindTerm (\i => either (f i) (g i))
public export
coproducts : {z : RawAlgebra sig} -> IFunc x z.U -> IFunc y z.U -> (ts : _)
-> CoproductSet sig x y ^ ts -> z.U ^ ts
-coproducts f g _ = bindTerms (\i => either (f i) (g i))
+coproducts f g = bindTerms (\i => either (f i) (g i))
+
+public export
+coproductCong' : {x, y, z : Algebra sig}
+ -> (f, f' : Homomorphism x z) -> (g, g' : Homomorphism y z)
+ -> (congL : (t : _) -> {i, j : x.raw.U t} -> x.relation t i j
+ -> z.relation t (f.func t i) (f'.func t j))
+ -> (congR : (t : _) -> {i, j : y.raw.U t} -> y.relation t i j
+ -> z.relation t (g.func t i) (g'.func t j))
+ -> (t : sig.T) -> {tm, tm' : _} -> (~=~) x.rawWithRelation y.rawWithRelation t tm tm'
+ -> z.relation t
+ (coproduct {z = z.raw} f.func g.func t tm)
+ (coproduct {z = z.raw} f'.func g'.func t tm')
+
+public export
+coproductsCong' : {x, y, z : Algebra sig}
+ -> (f, f' : Homomorphism x z) -> (g, g' : Homomorphism y z)
+ -> (congL : (t : _) -> {i, j : x.raw.U t} -> x.relation t i j
+ -> z.relation t (f.func t i) (f'.func t j))
+ -> (congR : (t : _) -> {i, j : y.raw.U t} -> y.relation t i j
+ -> z.relation t (g.func t i) (g'.func t j))
+ -> (ts : List sig.T) -> {tms, tms' : _ ^ ts}
+ -> Pointwise ((~=~) x.rawWithRelation y.rawWithRelation) tms tms'
+ -> Pointwise z.relation
+ (coproducts {z = z.raw} f.func g.func ts tms)
+ (coproducts {z = z.raw} f'.func g'.func ts tms')
+
+coproductCong' f f' g g' congL congR _ (DoneL eq) = congL _ eq
+coproductCong' f f' g g' congL congR _ (DoneR eq) = congR _ eq
+coproductCong' f f' g g' congL congR _ (Call op eqs) =
+ z.algebra.semCong op $
+ coproductsCong' f f' g g' congL congR _ eqs
+coproductCong' f f' g g' congL congR _ (InjectL op ts) = CalcWith (z.setoid.index _) $
+ |~ f.func _ (x.raw.sem op ts)
+ ~~ f'.func _ (x.raw.sem op ts) ...(congL _ $ (x.algebra.equivalence _).reflexive {x = x.raw.sem op ts})
+ ~~ z.raw.sem op (map f'.func ts) ...(f'.homo.semHomo op ts)
+ ~~ z.raw.sem op (map (coproduct f'.func g'.func) (map (\_ => Done . Left) ts)) .=.(cong (z.raw.sem op) $ mapComp ts)
+ ~~ z.raw.sem op (coproducts f'.func g'.func _ (map (\_ => Done . Left) ts)) .=<(cong (z.raw.sem op) $ bindTermsIsMap {a = z.raw} _ _)
+coproductCong' f f' g g' congL congR _ (InjectR op ts) = CalcWith (z.setoid.index _) $
+ |~ g.func _ (y.raw.sem op ts)
+ ~~ g'.func _ (y.raw.sem op ts) ...(congR _ $ (y.algebra.equivalence _).reflexive {x = y.raw.sem op ts})
+ ~~ z.raw.sem op (map g'.func ts) ...(g'.homo.semHomo op ts)
+ ~~ z.raw.sem op (map (coproduct f'.func g'.func) (map (\_ => Done . Right) ts)) .=.(cong (z.raw.sem op) $ mapComp ts)
+ ~~ z.raw.sem op (coproducts f'.func g'.func _ (map (\_ => Done . Right) ts)) .=<(cong (z.raw.sem op) $ bindTermsIsMap {a = z.raw} _ _)
+coproductCong' f f' g g' congL congR _ (Sym eq) =
+ (z.algebra.equivalence _).symmetric $
+ coproductCong' f' f g' g
+ (\t => (z.algebra.equivalence t).symmetric . congL t . (x.algebra.equivalence t).symmetric)
+ (\t => (z.algebra.equivalence t).symmetric . congR t . (y.algebra.equivalence t).symmetric)
+ _
+ eq
+coproductCong' f f' g g' congL congR _ (Trans eq eq') = (z.algebra.equivalence _).transitive
+ (coproductCong' f f g g f.homo.cong g.homo.cong _ eq)
+ (coproductCong' f f' g g' congL congR _ eq')
+
+coproductsCong' f f' g g' congL congR _ [] = []
+coproductsCong' f f' g g' congL congR _ (eq :: eqs) =
+ coproductCong' f f' g g' congL congR _ eq :: coproductsCong' f f' g g' congL congR _ eqs
public export
coproductCong : {x, y, z : Algebra sig}
-> (f : Homomorphism x z) -> (g : Homomorphism y z)
-> (t : sig.T) -> {tm, tm' : _} -> (~=~) x.rawWithRelation y.rawWithRelation t tm tm'
-> (z.relation t `on` coproduct {z = z.raw} f.func g.func t) tm tm'
+coproductCong f g = coproductCong' f f g g f.homo.cong g.homo.cong
public export
coproductsCong : {x, y, z : Algebra sig}
@@ -135,30 +178,7 @@ coproductsCong : {x, y, z : Algebra sig}
-> (ts : List sig.T) -> {tms, tms' : _ ^ ts}
-> Pointwise ((~=~) x.rawWithRelation y.rawWithRelation) tms tms'
-> (Pointwise z.relation `on` (coproducts {z = z.raw} f.func g.func ts)) tms tms'
-
-coproductCong f g _ (DoneL eq) = f.homo.cong _ eq
-coproductCong f g _ (DoneR eq) = g.homo.cong _ eq
-coproductCong f g _ (Call op eqs) =
- z.algebra.semCong op $
- coproductsCong f g _ eqs
-coproductCong f g _ (InjectL op ts) = CalcWith (z.setoid.index _) $
- |~ f.func _ (x.raw.sem op ts)
- ~~ z.raw.sem op (map f.func ts) ...(f.homo.semHomo op ts)
- ~~ z.raw.sem op (map (coproduct f.func g.func) (map (\_ => Done . Left) ts)) .=.(cong (z.raw.sem op) $ mapComp ts)
- ~~ z.raw.sem op (coproducts f.func g.func _ (map (\_ => Done . Left) ts)) .=<(cong (z.raw.sem op) $ bindTermsIsMap {a = z.raw} _ _)
-coproductCong f g _ (InjectR op ts) = CalcWith (z.setoid.index _) $
- |~ g.func _ (y.raw.sem op ts)
- ~~ z.raw.sem op (map g.func ts) ...(g.homo.semHomo op ts)
- ~~ z.raw.sem op (map (coproduct f.func g.func) (map (\_ => Done . Right) ts)) .=.(cong (z.raw.sem op) $ mapComp ts)
- ~~ z.raw.sem op (coproducts f.func g.func _ (map (\_ => Done . Right) ts)) .=<(cong (z.raw.sem op) $ bindTermsIsMap {a = z.raw} _ _)
-coproductCong f g _ (Sym eq) = (z.algebra.equivalence _).symmetric $ coproductCong f g _ eq
-coproductCong f g _ (Trans eq eq') = (z.algebra.equivalence _).transitive
- (coproductCong f g _ eq)
- (coproductCong f g _ eq')
-
-coproductsCong f g _ [] = []
-coproductsCong f g _ (eq :: eqs) =
- coproductCong f g _ eq :: coproductsCong f g _ eqs
+coproductsCong f g = coproductsCong' f f g g f.homo.cong g.homo.cong
public export
coproductIsHomo : {x, y, z : Algebra sig} -> (f : Homomorphism x z) -> (g : Homomorphism y z)
diff --git a/src/Soat/FirstOrder/Algebra/FreeExtension.idr b/src/Soat/FirstOrder/Algebra/FreeExtension.idr
new file mode 100644
index 0000000..675c65b
--- /dev/null
+++ b/src/Soat/FirstOrder/Algebra/FreeExtension.idr
@@ -0,0 +1,58 @@
+module Soat.FirstOrder.Algebra.FreeExtension
+
+import Data.Morphism.Indexed
+import Data.Setoid.Indexed
+
+import Soat.FirstOrder.Algebra
+import Soat.FirstOrder.Algebra.Coproduct
+import Soat.FirstOrder.Signature
+import Soat.FirstOrder.Term
+
+%default total
+
+public export
+FreeExtension : (a : RawAlgebra sig) -> (v : sig.T -> Type) -> RawAlgebra sig
+FreeExtension a v = Coproduct a (Free v)
+
+public export
+FreeExtensionAlgebra : (a : Algebra sig) -> (v : ISetoid sig.T) -> Algebra sig
+FreeExtensionAlgebra a v = CoproductAlgebra a (FreeAlgebra v)
+
+public export
+extend : {a : RawAlgebra sig} -> {u : sig.T -> Type} -> (f : IFunc v u)
+ -> IFunc (FreeExtension a v).U (FreeExtension a u).U
+extend f = coproduct {z = FreeExtension a u}
+ (\_ => Done . Left)
+ (\t => Done . Right . free f t)
+
+public export
+extendHomo : {a : Algebra sig} -> {v, u : ISetoid sig.T} -> (f : IFunction v u)
+ -> Homomorphism (FreeExtensionAlgebra a v) (FreeExtensionAlgebra a u)
+extendHomo f = coproductHomo {z = FreeExtensionAlgebra a u}
+ (injectLHomo {y = FreeAlgebra u})
+ (compHomo injectRHomo (freeHomo f))
+
+public export
+extendCong : {a : Algebra sig} -> {v, u : ISetoid sig.T} -> (f : IFunction v u)
+ -> (t : sig.T) -> {tm, tm' : (FreeExtension a.raw v.U).U t}
+ -> (FreeExtensionAlgebra a v).relation t tm tm'
+ -> ((FreeExtensionAlgebra a u).relation t `on` extend {a = a.raw} f.func t) tm tm'
+extendCong f = coproductCong {z = FreeExtensionAlgebra a u}
+ (injectLHomo {y = FreeAlgebra u})
+ (compHomo injectRHomo (freeHomo f))
+
+public export
+extendUnique : {a : Algebra sig} -> {v, u : ISetoid sig.T}
+ -> (f : IFunction v u)
+ -> (g : Homomorphism (FreeExtensionAlgebra a v) (FreeExtensionAlgebra a u))
+ -> (congL : {t : sig.T} -> (i : a.raw.U t)
+ -> (FreeExtensionAlgebra a u).relation t (g.func t (Done (Left i))) (Done (Left i)))
+ -> (congR : {t : sig.T} -> (i : Term sig v.U t)
+ -> (FreeExtensionAlgebra a u).relation t
+ (g.func t (Done (Right i)))
+ (Done (Right (free f.func t i))))
+ -> {t : sig.T} -> (tm : _)
+ -> (FreeExtensionAlgebra a u).relation t (g.func t tm) (extend {a = a.raw} f.func t tm)
+extendUnique f = coproductUnique {z = FreeExtensionAlgebra a u}
+ (injectLHomo {y = FreeAlgebra u})
+ (compHomo injectRHomo (freeHomo f))
diff --git a/src/Soat/FirstOrder/Term.idr b/src/Soat/FirstOrder/Term.idr
index 4a51f94..dc0c182 100644
--- a/src/Soat/FirstOrder/Term.idr
+++ b/src/Soat/FirstOrder/Term.idr
@@ -15,25 +15,6 @@ data Term : (0 sig : Signature) -> (0 _ : sig.T -> Type) -> sig.T -> Type where
Done : (i : v t) -> Term sig v t
Call : (op : Op sig t) -> (ts : Term sig v ^ op.arity) -> Term sig v t
-public export
-bindTerm : {auto a : RawAlgebra sig} -> IFunc v a.U -> {t : _} -> Term sig v t -> a.U t
-
-public export
-bindTerms : {auto a : RawAlgebra sig} -> IFunc v a.U -> {ts : _} -> Term sig v ^ ts -> a.U ^ ts
-
-bindTerm env (Done i) = env _ i
-bindTerm {a = a} env (Call op ts) = a.sem op (bindTerms env ts)
-
-bindTerms env [] = []
-bindTerms env (t :: ts) = bindTerm env t :: bindTerms env ts
-
-public export
-bindTermsIsMap : {auto a : RawAlgebra sig}
- -> (env : IFunc v a.U) -> {ts : _} -> (tms : Term sig v ^ ts)
- -> bindTerms (\tm => env tm) tms = map (\t => bindTerm (\tm => env tm)) tms
-bindTermsIsMap env [] = Refl
-bindTermsIsMap env (t :: ts) = cong ((::) (bindTerm env t)) (bindTermsIsMap env ts)
-
-- FIXME: these names shouldn't be public. Indication of bad API design
namespace Rel
public export
@@ -138,42 +119,85 @@ FreeAlgebra : ISetoid sig.T -> Algebra sig
FreeAlgebra v = MkAlgebra _ _ (FreeIsAlgebra v)
public export
+inject : IFunc v (Term sig v)
+inject _ = Done
+
+public export
+injectFunc : IFunction v (FreeAlgebra v).setoid
+injectFunc = MkIFunction (\_ => Done) (\_ => Done')
+
+public export
+bindTerm : {auto a : RawAlgebra sig} -> IFunc v a.U -> IFunc (Term sig v) a.U
+
+public export
+bindTerms : {auto a : RawAlgebra sig} -> IFunc v a.U -> IFunc ((^) (Term sig v)) ((^) a.U)
+
+bindTerm env _ (Done i) = env _ i
+bindTerm env _ (Call op ts) = a.sem op (bindTerms env _ ts)
+
+bindTerms env _ [] = []
+bindTerms env _ (t :: ts) = bindTerm env _ t :: bindTerms env _ ts
+
+public export
+free : IFunc v u -> IFunc (Term sig v) (Term sig u)
+free f = bindTerm {a = Free u} (\i => inject i . f i)
+
+public export
+bindTermsIsMap : {a : RawAlgebra sig}
+ -> (env : IFunc v a.U) -> {ts : _} -> (tms : Term sig v ^ ts)
+ -> bindTerms (\tm => env tm) _ tms = map (bindTerm (\tm => env tm)) tms
+bindTermsIsMap env [] = Refl
+bindTermsIsMap env (t :: ts) = cong ((::) (bindTerm env _ t)) (bindTermsIsMap env ts)
+
+public export
bindTermCong' : {a : Algebra sig} -> {env, env' : IFunc v a.raw.U} -> {0 rel : IRel v}
-> (cong : (t : sig.T) -> {x, y : v t} -> rel t x y -> a.relation t (env t x) (env' t y))
- -> {t : sig.T} -> {tm, tm' : Term sig v t} -> (~=~) rel t tm tm'
- -> a.relation t (bindTerm {a = a.raw} env tm) (bindTerm {a = a.raw} env' tm')
+ -> (t : sig.T) -> {tm, tm' : Term sig v t} -> (~=~) rel t tm tm'
+ -> a.relation t (bindTerm {a = a.raw} env t tm) (bindTerm {a = a.raw} env' t tm')
public export
bindTermsCong' : {a : Algebra sig} -> {env, env' : IFunc v a.raw.U} -> {0 rel : IRel v}
-> (cong : (t : sig.T) -> {x, y : v t} -> rel t x y -> a.relation t (env t x) (env' t y))
- -> {ts : List sig.T} -> {tms, tms' : Term sig v ^ ts} -> Pointwise ((~=~) rel) tms tms'
- -> Pointwise a.relation (bindTerms {a = a.raw} env tms) (bindTerms {a = a.raw} env' tms')
+ -> (ts : List sig.T) -> {tms, tms' : Term sig v ^ ts} -> Pointwise ((~=~) rel) tms tms'
+ -> Pointwise a.relation (bindTerms {a = a.raw} env _ tms) (bindTerms {a = a.raw} env' _ tms')
-bindTermCong' cong (Done' i) = cong _ i
-bindTermCong' {a = a} cong (Call' op ts) = a.algebra.semCong op (bindTermsCong' cong ts)
+bindTermCong' cong _ (Done' i) = cong _ i
+bindTermCong' cong _ (Call' op ts) = a.algebra.semCong op (bindTermsCong' cong _ ts)
-bindTermsCong' cong [] = []
-bindTermsCong' cong (t :: ts) = bindTermCong' cong t :: bindTermsCong' cong ts
+bindTermsCong' cong _ [] = []
+bindTermsCong' cong _ (t :: ts) = bindTermCong' cong _ t :: bindTermsCong' cong _ ts
+
+public export
+freeCong' : {u : ISetoid sig.T} -> {f, g : IFunc v u.U} -> {0 rel : IRel v}
+ -> (cong : (t : sig.T) -> {i, j : v t} -> rel t i j -> u.relation t (f t i) (g t j))
+ -> (t : sig.T) -> {tm, tm' : Term sig v t}
+ -> (~=~) rel t tm tm' -> (~=~) u.relation t (free f t tm) (free g t tm')
+freeCong' cong = bindTermCong' {a = FreeAlgebra u} (\i => Done' . cong i)
public export
bindTermCong : {a : Algebra sig} -> (env : IFunction v a.setoid)
- -> {t : sig.T} -> {tm, tm' : Term sig v.U t} -> (~=~) v.relation t tm tm'
- -> a.relation t (bindTerm {a = a.raw} env.func tm) (bindTerm {a = a.raw} env.func tm')
+ -> (t : sig.T) -> {tm, tm' : Term sig v.U t} -> (~=~) v.relation t tm tm'
+ -> a.relation t (bindTerm {a = a.raw} env.func t tm) (bindTerm {a = a.raw} env.func t tm')
bindTermCong env = bindTermCong' env.cong
public export
bindTermsCong : {a : Algebra sig} -> (env : IFunction v a.setoid)
- -> {ts : List sig.T} -> {tms, tms' : Term sig v.U ^ ts} -> Pointwise ((~=~) v.relation) tms tms'
+ -> (ts : List sig.T) -> {tms, tms' : Term sig v.U ^ ts} -> Pointwise ((~=~) v.relation) tms tms'
-> Pointwise a.relation
- (bindTerms {a = a.raw} env.func tms)
- (bindTerms {a = a.raw} env.func tms')
+ (bindTerms {a = a.raw} env.func ts tms)
+ (bindTerms {a = a.raw} env.func ts tms')
bindTermsCong env = bindTermsCong' env.cong
public export
+freeCong : {u : ISetoid sig.T} -> (f : IFunction v u) -> (t : sig.T) -> {tm, tm' : Term sig v.U t}
+ -> (~=~) v.relation t tm tm' -> (~=~) u.relation t (free f.func t tm) (free f.func t tm')
+freeCong f = freeCong' f.cong
+
+public export
bindIsHomo : (a : Algebra sig) -> (env : IFunction v a.setoid)
- -> IsHomomorphism (FreeAlgebra v) a (\t => bindTerm {a = a.raw} env.func)
+ -> IsHomomorphism (FreeAlgebra v) a (bindTerm {a = a.raw} env.func)
bindIsHomo a env = MkIsHomomorphism
- (\t, eq => bindTermCong env eq)
+ (bindTermCong env)
(\op, tms =>
a.algebra.semCong op $
map (\t => (a.algebra.equivalence t).equalImpliesEq) $
@@ -185,14 +209,19 @@ bindHomo : {a : Algebra sig} -> (env : IFunction v a.setoid) -> Homomorphism (Fr
bindHomo env = MkHomomorphism _ (bindIsHomo _ env)
public export
-bindUnique' : {v : ISetoid sig.T} -> {a : Algebra sig}
+freeHomo : {u : ISetoid sig.T} -> IFunction v u
+ -> Homomorphism {sig = sig} (FreeAlgebra v) (FreeAlgebra u)
+freeHomo f = bindHomo $ compFunc injectFunc f
+
+public export
+bindUnique' : {0 v : ISetoid sig.T} -> {a : Algebra sig}
-> (f, g : Homomorphism (FreeAlgebra v) a)
-> (cong : {t : sig.T} -> (i : v.U t) -> a.relation t (f.func t (Done i)) (g.func t (Done i)))
-> {t : sig.T} -> (tm : Term sig v.U t)
-> a.relation t (f.func t tm) (g.func t tm)
public export
-bindsUnique' : {v : ISetoid sig.T} -> {a : Algebra sig}
+bindsUnique' : {0 v : ISetoid sig.T} -> {a : Algebra sig}
-> (f, g : Homomorphism (FreeAlgebra v) a)
-> (cong : {t : sig.T} -> (i : v.U t) -> a.relation t (f.func t (Done i)) (g.func t (Done i)))
-> {ts : List sig.T} -> (tms : Term sig v.U ^ ts)
@@ -213,7 +242,7 @@ bindUnique : {v : ISetoid sig.T} -> {a : Algebra sig} -> (env : IFunction v a.se
-> (f : Homomorphism (FreeAlgebra v) a)
-> (cong : {t : sig.T} -> (i : v.U t) -> a.relation t (f.func t (Done i)) (env.func t i))
-> {t : sig.T} -> (tm : Term sig v.U t)
- -> a.relation t (f.func t tm) (bindTerm {a = a.raw} env.func tm)
+ -> a.relation t (f.func t tm) (bindTerm {a = a.raw} env.func t tm)
bindUnique env f = bindUnique' f (bindHomo env)
public export
@@ -221,8 +250,17 @@ bindsUnique : {v : ISetoid sig.T} -> {a : Algebra sig} -> (env : IFunction v a.s
-> (f : Homomorphism (FreeAlgebra v) a)
-> (cong : {t : sig.T} -> (i : v.U t) -> a.relation t (f.func t (Done i)) (env.func t i))
-> {ts : List sig.T} -> (tms : Term sig v.U ^ ts)
- -> Pointwise a.relation (map f.func tms) (bindTerms {a = a.raw} env.func tms)
+ -> Pointwise a.relation (map f.func tms) (bindTerms {a = a.raw} env.func ts tms)
bindsUnique env f cong ts = CalcWith (pwSetoid a.setoid _) $
|~ map f.func ts
- ~~ map (\_ => bindTerm {a = a.raw} env.func) ts ...( bindsUnique' f (bindHomo env) cong ts )
- ~~ bindTerms {a = a.raw} env.func ts .=<( bindTermsIsMap {a = a.raw} env.func ts )
+ ~~ map (bindTerm {a = a.raw} env.func) ts ...( bindsUnique' f (bindHomo env) cong ts )
+ ~~ bindTerms {a = a.raw} env.func _ ts .=<( bindTermsIsMap {a = a.raw} env.func ts )
+
+public export
+freeUnique : {v, u : ISetoid sig.T} -> (f : IFunction v u)
+ -> (g : Homomorphism (FreeAlgebra v) (FreeAlgebra u))
+ -> (cong : {t : sig.T} -> (i : v.U t)
+ -> (FreeAlgebra u).relation t (g.func t (Done i)) (Done (f.func t i)))
+ -> {t : sig.T} -> (tm : Term sig v.U t)
+ -> (FreeAlgebra u).relation t (g.func t tm) (free f.func t tm)
+freeUnique f = bindUnique $ compFunc injectFunc f
diff --git a/src/Soat/SecondOrder/Algebra.idr b/src/Soat/SecondOrder/Algebra.idr
index c506c85..f28d4bc 100644
--- a/src/Soat/SecondOrder/Algebra.idr
+++ b/src/Soat/SecondOrder/Algebra.idr
@@ -18,6 +18,11 @@ extendRel : {U : a -> List a -> Type} -> (rel : IRel (uncurry U))
extendRel rel ctx ty = rel (snd ty, fst ty ++ ctx)
public export
+extendFunc : {0 U, V : a -> List a -> Type} -> (f : (t : a) -> IFunc (U t) (V t)) -> (ctx : List a)
+ -> IFunc (extend U ctx) (extend V ctx)
+extendFunc f ctx ty = f (snd ty) (fst ty ++ ctx)
+
+public export
algebraOver : (sig : Signature) -> (U : sig.T -> List sig.T -> Type) -> Type
algebraOver sig x = (ctx : List sig.T) -> {t : sig.T} -> (op : Op sig t)
-> extend x ctx ^ op.arity -> x t ctx
@@ -26,13 +31,23 @@ public export
record RawAlgebra (0 sig : Signature) where
constructor MakeRawAlgebra
0 U : (t : sig.T) -> (ctx : List sig.T) -> Type
- rename : (t : sig.T) -> forall ctx, ctx' . (f : ctx `Sublist` ctx') -> U t ctx -> U t ctx'
+ rename : (t : sig.T) -> {ctx, ctx' : _} -> (f : ctx `Sublist` ctx') -> U t ctx -> U t ctx'
sem : sig `algebraOver` U
var : forall t, ctx . (i : Elem t ctx) -> U t ctx
subst : (t : sig.T) -> (ctx : List sig.T)
-> forall ctx' . U t ctx' -> (\t => U t ctx) ^ ctx' -> U t ctx
public export
+(.extendSubst) : (a : RawAlgebra sig) -> (ctx : _) -> {ctx' : _}
+ -> (tms : (\t => a.U t ctx) ^ ctx') -> IFunc (extend a.U ctx') (extend a.U ctx)
+(.extendSubst) a ctx tms ty tm = a.subst
+ (snd ty)
+ (fst ty ++ ctx)
+ tm
+ (tabulate {is = fst ty} (a.var . Sublist.elemJoinL {ys = ctx}) ++
+ map (\t => a.rename t ([] {ys = fst ty} ++ Relation.reflexive {x = ctx})) tms)
+
+public export
record IsAlgebra (0 sig : Signature) (0 a : RawAlgebra sig) (0 rel : IRel (uncurry a.U)) where
constructor MkIsAlgebra
equivalence : IEquivalence (uncurry a.U) rel
@@ -94,12 +109,7 @@ record IsAlgebra (0 sig : Signature) (0 a : RawAlgebra sig) (0 rel : IRel (uncur
-> {ctx' : _} -> (tms : extend a.U ctx' ^ op.arity) -> (tms' : (\t => a.U t ctx) ^ ctx')
-> rel (t, ctx)
(a.subst t ctx (a.sem ctx' op tms) tms')
- (a.sem ctx op $
- map (\ty, tm =>
- a.subst (snd ty) (fst ty ++ ctx) tm
- (tabulate {is = fst ty} (a.var . Sublist.elemJoinL {ys = ctx}) ++
- map (\t => a.rename t ([] {ys = fst ty} ++ Relation.reflexive {x = ctx})) tms')) $
- tms)
+ (a.sem ctx op $ map (a.extendSubst ctx tms') $ tms)
public export
record Algebra (0 sig : Signature) where
@@ -139,7 +149,7 @@ record IsHomomorphism
-> (tms : extend a.raw.U ctx ^ op.arity)
-> b.relation (t, ctx)
(f t ctx $ a.raw.sem ctx op tms)
- (b.raw.sem ctx op $ map (\ty => f (snd ty) (fst ty ++ ctx)) tms)
+ (b.raw.sem ctx op $ map (extendFunc f ctx) tms)
varHomo : {t : _} -> {ctx : _} -> (i : Elem t ctx)
-> b.relation (t, ctx) (f t ctx $ a.raw.var i) (b.raw.var i)
substHomo : (t : sig.T) -> (ctx : List sig.T) -> {ctx' : _} -> (tm : a.raw.U t ctx')
diff --git a/src/Soat/SecondOrder/Algebra/Lift.idr b/src/Soat/SecondOrder/Algebra/Lift.idr
index b08eb0e..61852f2 100644
--- a/src/Soat/SecondOrder/Algebra/Lift.idr
+++ b/src/Soat/SecondOrder/Algebra/Lift.idr
@@ -6,11 +6,17 @@ import Data.Setoid.Indexed
import Soat.Data.Product
import Soat.Data.Sublist
+
import Soat.FirstOrder.Algebra
+import Soat.FirstOrder.Algebra.Coproduct
+import Soat.FirstOrder.Algebra.FreeExtension
import Soat.FirstOrder.Term
+
import Soat.SecondOrder.Algebra
import Soat.SecondOrder.Signature.Lift
+import Syntax.PreorderReasoning.Setoid
+
%default total
public export
@@ -35,17 +41,17 @@ projectAlgebra a ctx = MkAlgebra _ _ (projectIsAlgebra a.algebra ctx)
public export
projectIsHomo : {a, b : SecondOrder.Algebra.Algebra (lift sig)} -> {f : _} -> IsHomomorphism a b f
- -> (ctx : _)
+ -> (ctx : List sig.T)
-> IsHomomorphism {sig = sig} (projectAlgebra a ctx) (projectAlgebra b ctx) (\t => f t ctx)
-projectIsHomo {b = b} f ctx = MkIsHomomorphism
- (\t => f.cong t ctx)
- (\op, tms =>
- (b.algebra.equivalence _).transitive
- (f.semHomo ctx (MkOp (Op op.op)) (wrap (MkPair []) tms)) $
- b.algebra.semCong ctx (MkOp (Op op.op)) $
- map (\(_,_) => (b.algebra.equivalence _).equalImpliesEq) $
- equalImpliesPwEq $
- mapWrap (MkPair []) tms)
+projectIsHomo {b = b} homo ctx = MkIsHomomorphism
+ { cong = \t => homo.cong t ctx
+ , semHomo = \op, tms => CalcWith (b.setoid.index _) $
+ |~ f _ ctx (a.raw.sem ctx (MkOp (Op op.op)) (wrap (MkPair []) tms))
+ ~~ b.raw.sem ctx (MkOp (Op op.op)) (map (extendFunc f ctx) (wrap (MkPair []) tms))
+ ...(homo.semHomo ctx (MkOp (Op op.op)) (wrap (MkPair []) tms))
+ ~~ b.raw.sem ctx (MkOp (Op op.op)) (wrap (MkPair []) (map (\t => f t ctx) tms))
+ .=.(cong (b.raw.sem ctx (MkOp (Op op.op))) $ mapWrap (MkPair []) {f = extendFunc f ctx} tms)
+ }
public export
projectHomo : {a, b : SecondOrder.Algebra.Algebra (lift sig)} -> Homomorphism a b
@@ -57,88 +63,77 @@ public export
-> (f : ctx `Sublist` ctx')
-> FirstOrder.Algebra.Homomorphism {sig = sig} (projectAlgebra a ctx) (projectAlgebra a ctx')
(.renameHomo) a f = MkHomomorphism
- (\t => a.raw.rename t f)
- (MkIsHomomorphism
- (\t => a.algebra.renameCong t f)
- (\op, tms => (a.algebra.equivalence _).transitive
- (a.algebra.semNat f (MkOp (Op op.op)) (wrap (MkPair []) tms))
- (a.algebra.semCong _ (MkOp (Op op.op)) $
- map (\(_,_) => (a.algebra.equivalence _).equalImpliesEq) $
- pwSym (\_ => MkSymmetric symmetric) $
- pwTrans (\_ => MkTransitive transitive)
- (wrapIntro $
- mapIntro'' (\t, tm, _, Refl =>
- cong (\f => a.raw.rename t f tm) $
- sym $
- uncurryCurry f) $
- equalImpliesPwEq Refl) $
- equalImpliesPwEq $
- sym $
- mapWrap (MkPair []) tms)))
+ { func = \t => a.raw.rename t f
+ , homo = MkIsHomomorphism
+ { cong = \t => a.algebra.renameCong t f
+ , semHomo = \op, tms => CalcWith (a.setoid.index _) $
+ |~ a.raw.rename _ f (a.raw.sem _ (MkOp (Op op.op)) (wrap (MkPair []) tms))
+ ~~ a.raw.sem _ (MkOp (Op op.op)) (map (\ty => a.raw.rename (snd ty) (reflexive {x = fst ty} ++ f)) (wrap (MkPair []) tms))
+ ...(a.algebra.semNat f (MkOp (Op op.op)) (wrap (MkPair []) tms))
+ ~~ a.raw.sem _ (MkOp (Op op.op)) (wrap (MkPair []) (map (\t => a.raw.rename t f) tms))
+ ...(a.algebra.semCong _ (MkOp (Op op.op)) $
+ CalcWith (pwSetoid (a.setoid.reindex (\ty => (snd ty, fst ty ++ _))) _) $
+ |~ map (\ty => a.raw.rename (snd ty) (reflexive {x = fst ty} ++ f)) (wrap (MkPair []) tms)
+ ~~ wrap (MkPair []) (map (\t => a.raw.rename t (reflexive {x = []} ++ f)) tms)
+ .=.(mapWrap (MkPair []) tms)
+ ~~ wrap (MkPair []) (map (\t => a.raw.rename t f) tms)
+ .=.(cong (wrap (MkPair [])) $
+ pwEqImpliesEqual $
+ mapIntro'' (\t, tm, _, Refl => cong (\f => a.raw.rename t f tm) $ uncurryCurry f) $
+ equalImpliesPwEq Refl))
+ }
+ }
public export
(.substHomo1) : (a : SecondOrder.Algebra.Algebra (lift sig)) -> (ctx : List sig.T)
-> {ctx' : List sig.T} -> (tms : (\t => a.raw.U t ctx) ^ ctx')
-> FirstOrder.Algebra.Homomorphism {sig = sig} (projectAlgebra a ctx') (projectAlgebra a ctx)
(.substHomo1) a ctx tms = MkHomomorphism
- (\t, tm => a.raw.subst t ctx tm tms)
- (MkIsHomomorphism
- (\t, eq => a.algebra.substCong t ctx eq $ pwRefl (\_ => (a.algebra.equivalence _).refl))
- (\op, tms' => (a.algebra.equivalence _).transitive
- (a.algebra.substCompat ctx (MkOp (Op op.op)) (wrap (MkPair []) tms') tms)
- (a.algebra.semCong ctx (MkOp (Op op.op)) $
- pwSym (\(_,_) => (a.algebra.equivalence _).sym) $
- pwTrans (\(_,_) => (a.algebra.equivalence _).trans)
- (pwSym (\(_,_) => (a.algebra.equivalence _).sym) $
- wrapIntro $
- mapIntro'' (\t, tm, _, Refl =>
- a.algebra.substCong t ctx (a.algebra.equivalence _).reflexive $
- pwTrans (\_ => (a.algebra.equivalence _).trans)
- (mapIntro'' (\t, tm, _, Refl => (a.algebra.equivalence _).transitive
- ((a.algebra.equivalence _).equalImpliesEq $
- cong (\f => a.raw.rename t f tm) $
- uncurryCurry reflexive)
- (a.algebra.renameId _ _ tm)) $
- equalImpliesPwEq Refl) $
- map (\_ => (a.algebra.equivalence _).equalImpliesEq) $
- equalImpliesPwEq $
- mapId tms) $
- equalImpliesPwEq Refl) $
- map (\(_,_) => (a.algebra.equivalence _).equalImpliesEq) $
- equalImpliesPwEq $
- sym $
- mapWrap (MkPair []) tms')))
-
-renameBodyFunc : (f : ctx `Sublist` ctx')
- -> IFunction
- (isetoid (flip Elem ctx))
- (FreeAlgebra {sig = sig} (isetoid (flip Elem ctx'))).setoid
-renameBodyFunc f = MkIFunction (\_ => Done . curry f) (\_ => Done' . cong (curry f))
+ { func = \t, tm => a.raw.subst t ctx tm tms
+ , homo = MkIsHomomorphism
+ { cong = \t, eq => a.algebra.substCong t ctx eq $ pwRefl (\_ => (a.algebra.equivalence _).refl)
+ , semHomo = \op, tms' => CalcWith (a.setoid.index _) $
+ |~ a.raw.subst _ ctx (a.raw.sem ctx' (MkOp (Op op.op)) (wrap (MkPair []) tms')) tms
+ ~~ a.raw.sem ctx (MkOp (Op op.op)) (map (a.raw.extendSubst ctx tms) (wrap (MkPair []) tms'))
+ ...(a.algebra.substCompat ctx (MkOp (Op op.op)) (wrap (MkPair []) tms') tms)
+ ~~ a.raw.sem ctx (MkOp (Op op.op)) (wrap (MkPair []) (map (\t, tm => a.raw.subst t ctx tm tms) tms'))
+ ...(a.algebra.semCong ctx (MkOp (Op op.op)) $
+ CalcWith (pwSetoid (a.setoid.reindex (\ty => (snd ty, fst ty ++ ctx))) _) $
+ |~ map (a.raw.extendSubst ctx tms) (wrap (MkPair []) tms')
+ ~~ wrap (MkPair []) (map (\t, tm => a.raw.subst t ctx tm (map (\t => a.raw.rename t ([] {ys = []} ++ reflexive)) tms)) tms')
+ .=.(mapWrap (MkPair []) tms')
+ ~~ wrap (MkPair []) (map (\t, tm => a.raw.subst t ctx tm tms) tms')
+ ...(wrapIntro $
+ mapIntro' (\t, eq =>
+ a.algebra.substCong t ctx eq $
+ CalcWith (pwSetoid (a.setoidAt _) _) $
+ |~ map (\t => a.raw.rename t ([] {ys = []} ++ reflexive)) tms
+ ~~ map (\t => a.raw.rename t reflexive) tms
+ .=.(pwEqImpliesEqual $
+ mapIntro' (\t => cong2 (a.raw.rename t) $ uncurryCurry reflexive) $
+ equalImpliesPwEq Refl)
+ ~~ map (\t => id) tms
+ ...(mapIntro' (\t, Refl => a.algebra.renameId t ctx _) $
+ equalImpliesPwEq Refl)
+ ~~ tms
+ .=.(mapId tms)) $
+ pwRefl (\t => (a.algebra.equivalence _).refl)))
+ }
+ }
-indexFunc : {ctx : List sig.T} -> (tms : Term sig (flip Elem ctx) ^ ts)
- -> IFunction
- (isetoid (flip Elem ts))
- (FreeAlgebra {sig = sig} (isetoid (flip Elem ctx))).setoid
+indexFunc : {x : ISetoid a} -> (tms : x.U ^ ts) -> IFunction (isetoid (flip Elem ts)) x
indexFunc tms = MkIFunction
(\_ => index tms)
- (\_ => ((FreeIsAlgebra (isetoid (flip Elem _))).equivalence _).equalImpliesEq . cong (index tms))
-
--- renameFunc : (f : ctx `Sublist` ctx')
--- -> IFunction
--- (FreeAlgebra {sig = sig} (isetoid (flip Elem ctx))).setoid
--- (FreeAlgebra {sig = sig} (isetoid (flip Elem ctx'))).setoid
--- renameFunc f = MkIFunction
--- (\_ => bindTerm {a = Free _} (renameBodyFunc f).func)
--- (\t => bindTermCong {a = FreeAlgebra (isetoid (flip Elem _))} (renameBodyFunc f))
+ (\_ => (x.equivalence _).equalImpliesEq . cong (index tms))
public export
Initial : (0 sig : _) -> SecondOrder.Algebra.RawAlgebra (lift sig)
Initial sig = MakeRawAlgebra
(\t, ctx => Term sig (flip Elem ctx) t)
- (\t, f => bindTerm {a = Free _} (renameBodyFunc f).func)
+ (\t, f => free (\_ => curry f) t)
(\_, (MkOp (Op op)) => Call (MkOp op) . unwrap (MkPair []))
Done
- (\_, _, t, ts => bindTerm {a = Free _} (\_ => index ts) t)
+ (\t, _, tm, tms => bindTerm {a = Free _} (\_ => index tms) t tm)
public export
InitialIsAlgebra : (0 sig : _)
@@ -147,91 +142,80 @@ InitialIsAlgebra : (0 sig : _)
(Initial sig)
(\(t, ctx) => (~=~) {sig = sig} {v = flip Elem ctx} (\_ => Equal) t)
InitialIsAlgebra sig = MkIsAlgebra
- (\(t, ctx) => tmRelEq (\_ => equiv) t)
- (\t, f => bindTermCong {a = FreeAlgebra (isetoid (flip Elem _))} (renameBodyFunc f))
- (\_ , (MkOp (Op op)) => Call' (MkOp op) . unwrapIntro)
- (\_, _, eq, eqs => bindTermCong'
+ { equivalence = \(t, ctx) => tmRelEq (\_ => equiv) t
+ , renameCong = \t, f => freeCong (ifunc (\_ => curry f)) t
+ , semCong = \_ , (MkOp (Op op)) => Call' (MkOp op) . unwrapIntro
+ , substCong = \_, _, eq, eqs => bindTermCong'
{a = FreeAlgebra (isetoid (flip Elem _))}
(\t, Refl => index eqs _)
- eq)
- (\t, ctx, tm =>
+ _
+ eq
+ , renameId = \t, ctx, tm =>
tmRelSym (\_ => MkSymmetric symmetric) $
- bindUnique (renameBodyFunc reflexive) idHomo (\i => Done' $ sym $ curryUncurry id i) $
- tm)
- (\t, f, g, tm =>
+ freeUnique (ifunc (\_ => curry reflexive)) idHomo (\i => Done' $ sym $ curryUncurry id i) $
+ tm
+ , renameComp = \t, f, g, tm =>
tmRelSym (\_ => MkSymmetric symmetric) $
- bindUnique
- {a = FreeAlgebra (isetoid (flip Elem _))}
- (renameBodyFunc (transitive g f))
- (compHomo (bindHomo (renameBodyFunc f)) (bindHomo (renameBodyFunc g)))
+ freeUnique
+ (ifunc (\_ => curry (transitive g f)))
+ (compHomo (freeHomo (ifunc (\_ => curry f))) (freeHomo (ifunc (\_ => curry g))))
(\i => Done' $ sym $ curryUncurry (curry f . curry g) i) $
- tm)
- (\f, (MkOp (Op op)), tms =>
+ tm
+ , semNat = \f, (MkOp (Op op)), tms =>
Call' (MkOp op) $
- Pointwise.map (\_ => tmRelReflexive (\_ => MkReflexive reflexive)) $
- pwTrans (\_ => MkTransitive transitive) (equalImpliesPwEq $ bindTermsIsMap {a = Free _} _ _) $
- pwTrans (\_ => MkTransitive transitive)
- (mapIntro' (\t, eq =>
- tmRelEqualIsEqual $
- bindTermCong'
- {rel = \_ => Equal}
- {a = FreeAlgebra (isetoid (flip Elem _))}
- (\_, Refl => Done' $ sym $ curryUncurry (curry f) _) $
- tmRelReflexive (\_ => MkReflexive reflexive) $
- eq) $
- equalImpliesPwEq Refl) $
- equalImpliesPwEq $
- mapUnwrap _ _)
- -- Pointwise.map (\_ => tmRelReflexive (\_ => MkReflexive reflexive)) $
- -- transitive (equalImpliesPwEq $ bindTermsIsMap {a = Free _} _ (unwrap (MkPair []) tms)) $
- -- transitive
- -- (mapIntro
- -- (\t, eq =>
- -- bindTermCong'
- -- {v = isetoid (flip Elem _)}
- -- {a = FreeAlgebra (isetoid (flip Elem _))}
- -- (\_, Refl => Done' $ sym $ curryUncurry (curry f) _) $
- -- tmRelReflexive (\_ => MkReflexive reflexive) $
- -- eq) $
- -- equalImpliesPwEq Refl) $
- -- equalImpliesPwEq $
- -- mapUnwrap
- -- (MkPair [])
- -- (\ty => (renameFunc (reflexive ++ f)).func (snd ty))
- -- tms)
- (\_, _ => Done' Refl)
- (\t, f, tm, tms =>
+ CalcWith (pwSetoid (FreeAlgebra (isetoid (flip Elem _))).setoid _) $
+ |~ bindTerms {a = Free _} (\_ => Done . curry f) _ (unwrap (MkPair []) tms)
+ ~~ map (free (\_ => curry f)) (unwrap (MkPair []) tms)
+ .=.(bindTermsIsMap {a = Free _} _ _)
+ ~~ map (free (\_ => curry (reflexive {x = []} ++ f))) (unwrap (MkPair []) tms)
+ ..<(mapIntro' (\t =>
+ freeCong'
+ {rel = \_ => Equal}
+ {u = isetoid (flip Elem _)}
+ (\_, Refl => curryUncurry (curry f) _)
+ _) $
+ tmsRelRefl (\_ => MkReflexive reflexive) (unwrap (MkPair []) tms))
+ ~~ unwrap (MkPair []) (map (\ty => free (\_ => curry (reflexive {x = fst ty} ++ f)) (snd ty)) tms)
+ .=.(mapUnwrap (MkPair []) tms)
+ , varNat = \_, _ => Done' Refl
+ , substNat = \t, f, tm, tms =>
bindUnique
{a = FreeAlgebra (isetoid (flip Elem _))}
(indexFunc _)
- (compHomo (bindHomo (renameBodyFunc f)) (bindHomo (indexFunc tms)))
+ (compHomo
+ (freeHomo (ifunc (\_ => curry f)))
+ (bindHomo (indexFunc tms)))
(\i =>
tmRelReflexive (\_ => MkReflexive reflexive) $
sym $
indexMap tms i)
- tm)
- (\t, ctx, f, tm, tms =>
+ tm
+ , substExnat = \t, ctx, f, tm, tms =>
bindUnique
{a = FreeAlgebra (isetoid (flip Elem _))}
(indexFunc _)
- (compHomo (bindHomo (indexFunc tms)) (bindHomo (renameBodyFunc f)))
+ (compHomo
+ (bindHomo (indexFunc tms))
+ (freeHomo (ifunc (\_ => curry f))))
(\i =>
tmRelReflexive (\_ => MkReflexive reflexive) $
sym $
indexShuffle f i)
- tm)
- (\t, ctx, tm, tms, tms' =>
+ tm
+ , substComm = \t, ctx, tm, tms, tms' =>
bindUnique
{a = FreeAlgebra (isetoid (flip Elem _))}
(indexFunc _)
- (compHomo (bindHomo (indexFunc tms')) (bindHomo (indexFunc tms)))
+ (compHomo
+ (bindHomo (indexFunc tms'))
+ (bindHomo (indexFunc tms)))
(\i =>
tmRelReflexive (\_ => MkReflexive reflexive) $
sym $
indexMap tms i)
- tm)
- (\_, _, _ => tmRelRefl (\_ => MkReflexive reflexive) _)
- (\t, ctx, tm =>
+ tm
+ , substVarL = \_, _, _ => tmRelRefl (\_ => MkReflexive reflexive) _
+ , substVarR = \t, ctx, tm =>
tmRelSym (\_ => MkSymmetric symmetric) $
bindUnique
{a = FreeAlgebra (isetoid (flip Elem _))}
@@ -241,108 +225,113 @@ InitialIsAlgebra sig = MkIsAlgebra
tmRelReflexive (\_ => MkReflexive reflexive) $
sym $
indexTabulate Done i)
- tm)
- (\ctx, (MkOp (Op op)), tms, tms' =>
+ tm
+ , substCompat = \ctx, (MkOp (Op op)), tms, tms' =>
Call' (MkOp op) $
- tmsRelTrans (\_ => MkTransitive transitive)
- (tmsRelSym (\_ => MkSymmetric symmetric) $
- bindsUnique
- {a = FreeAlgebra (isetoid (flip Elem _))}
- (indexFunc tms')
- (bindHomo (indexFunc _))
- (\i =>
- (tmRelTrans (\_ => MkTransitive transitive)
- (tmRelReflexive (\_ => MkReflexive reflexive) $
- indexMap
- {f = (\_ => bindTerm {a = Free _} (\_ => Done . curry (uncurry (curry reflexive))))}
- tms'
- i) $
- tmRelSym (\_ => MkSymmetric symmetric) $
- (bindUnique
- {a = FreeAlgebra (isetoid (flip Elem _))}
- (renameBodyFunc _)
- idHomo
- (\i =>
- Done' $
- sym $
- transitive (curryUncurry (curry reflexive) i) (curryUncurry id i))
- (index tms' i))))
- (unwrap (MkPair []) tms)) $
- tmsRelReflexive (\_ => MkReflexive reflexive) $
- mapUnwrap _ _)
+ CalcWith (pwSetoid (FreeAlgebra (isetoid (flip Elem _))).setoid _) $
+ |~ bindTerms {a = Free _} (\_ => index tms') _ (unwrap (MkPair []) tms)
+ ~~ map (bindTerm {a = Free _} (\_ => index tms')) (unwrap (MkPair []) tms)
+ .=.(bindTermsIsMap {a = Free _} _ _)
+ ~~ map (\t => (Initial sig).extendSubst ctx tms' ([], t)) (unwrap (MkPair []) tms)
+ ..<(mapIntro' (\t => bindTermCong'
+ {rel = \_ => Equal}
+ {a = FreeAlgebra (isetoid (flip Elem _))}
+ (\t, Refl => CalcWith ((FreeAlgebra (isetoid (flip Elem _))).setoid.index _) $
+ |~ index (map (free (\_ => curry ([] {ys = []} ++ reflexive))) tms') _
+ ~~ free (\_ => curry ([] {ys = []} ++ reflexive)) _ (index tms' _)
+ .=.(indexMap tms' _)
+ ~~ index tms' _
+ ..<(freeUnique
+ (ifunc (\_ => curry ([] {ys = []} ++ reflexive)))
+ idHomo
+ (\i => Done' $ sym $ trans (curryUncurry _ i) (curryUncurry id i))
+ (index tms' _)))
+ _) $
+ tmsRelRefl (\_ => MkReflexive reflexive) $
+ unwrap (MkPair []) tms)
+ ~~ unwrap (MkPair []) (map ((Initial sig).extendSubst ctx tms') tms)
+ .=.(mapUnwrap (MkPair []) tms)
+ }
public export
InitialAlgebra : (0 sig : _) -> SecondOrder.Algebra.Algebra (lift sig)
InitialAlgebra sig = MkAlgebra (Initial sig) _ (InitialIsAlgebra sig)
public export
-freeToInitialIsHomo : (0 sig : _) -> (ctx : List sig.T)
- -> IsHomomorphism {sig = sig}
- (FreeAlgebra (isetoid (flip Elem ctx)))
- (projectAlgebra (InitialAlgebra sig) ctx)
- (\_ => Basics.id)
-freeToInitialIsHomo sig ctx = MkIsHomomorphism
- (\_ => id)
- (\(MkOp op), tms =>
- Call' (MkOp op) $
- tmsRelSym (\_ => MkSymmetric symmetric) $
- tmsRelReflexive (\_ => MkReflexive reflexive) $
- transitive (unwrapWrap _ _) (mapId tms))
-
-public export
-freeToInitialHomo : (0 sig : _) -> (ctx : List sig.T)
- -> Homomorphism {sig = sig}
+ProjectInitialIsFree : (0 sig : _) -> (ctx : List sig.T)
+ -> Isomorphism {sig = sig}
(FreeAlgebra (isetoid (flip Elem ctx)))
(projectAlgebra (InitialAlgebra sig) ctx)
-freeToInitialHomo sig ctx = MkHomomorphism (\_ => id) (freeToInitialIsHomo sig ctx)
+ProjectInitialIsFree sig ctx = MkIsomorphism
+ { to = MkHomomorphism
+ { func = \_ => id
+ , homo = MkIsHomomorphism
+ { cong = \_ => id
+ , semHomo = \(MkOp op), ts =>
+ Call' (MkOp op) $
+ tmsRelReflexive (\_ => MkReflexive Refl) $
+ sym $
+ trans (unwrapWrap (extend (Initial sig).U ctx) _) (mapId ts)
+ }
+ }
+ , from = MkHomomorphism
+ { func = \_ => id
+ , homo = MkIsHomomorphism
+ { cong = \_ => id
+ , semHomo = \(MkOp op), ts =>
+ Call' (MkOp op) $
+ tmsRelReflexive (\_ => MkReflexive Refl) $
+ trans (unwrapWrap (extend (Initial sig).U ctx) ts) (sym $ mapId ts)
+ }
+ }
+ , fromTo = \tm => tmRelRefl (\_ => MkReflexive Refl) tm
+ , toFrom = \tm => tmRelRefl (\_ => MkReflexive Refl) tm
+ }
public export
-fromInitial : (a : SecondOrder.Algebra.RawAlgebra (lift sig)) -> (t : sig.T) -> (ctx : List sig.T)
- -> (Initial sig).U t ctx -> a.U t ctx
-fromInitial a t ctx = bindTerm {a = project a ctx} (\_ => a.var)
+fromInitial : (a : RawAlgebra (lift sig))
+ -> (t : _) -> (ctx : _) -> (Initial sig).U t ctx -> a.U t ctx
+fromInitial a t ctx = bindTerm {a = project a ctx} (\_ => a.var) t
public export
fromInitialIsHomo : (a : SecondOrder.Algebra.Algebra (lift sig))
-> IsHomomorphism (InitialAlgebra sig) a (fromInitial a.raw)
fromInitialIsHomo a = MkIsHomomorphism
- (\t , ctx => bindTermCong {a = projectAlgebra a ctx} (a.varFunc ctx))
- (\t, f => bindUnique'
+ { cong = \t, ctx => bindTermCong {a = projectAlgebra a ctx} (a.varFunc ctx) t
+ , renameHomo = \t, f => bindUnique'
{v = isetoid (flip Elem _)}
{a = projectAlgebra a _}
- (compHomo (bindHomo (a.varFunc _)) (bindHomo (renameBodyFunc f)))
+ (compHomo (bindHomo (a.varFunc _)) (freeHomo (ifunc (\_ => curry f))))
(compHomo (a.renameHomo f) (bindHomo (a.varFunc _)))
- (\i => (a.algebra.equivalence _).symmetric $ a.algebra.varNat f i))
- (\ctx, (MkOp (Op op)), tms =>
+ (\i => (a.algebra.equivalence _).symmetric $ a.algebra.varNat f i)
+ , semHomo = \ctx, (MkOp (Op op)), tms =>
a.algebra.semCong ctx (MkOp (Op op)) $
- map (\_ => (a.algebra.equivalence _).equalImpliesEq) $
- equalImpliesPwEq $
- transitive
- (cong (wrap _) $ bindTermsIsMap {a = project a.raw _} (\_ => a.raw.var) $ unwrap _ tms) $
- transitive
- (sym $ mapWrap (MkPair []) {f = \_ => fromInitial a.raw _ _} $ unwrap _ tms) $
- cong (map _) $
- wrapUnwrap tms)
- (\_ => (a.algebra.equivalence _).reflexive)
- (\t, ctx, tm, tms => bindUnique'
- {v = isetoid (flip Elem _)}
- {a = projectAlgebra a _}
- (compHomo (bindHomo (a.varFunc _)) (bindHomo (indexFunc tms)))
- (compHomo (a.substHomo1 ctx _) (bindHomo (a.varFunc _)))
- (\i =>
- (a.algebra.equivalence _).transitive
- (bindUnique
- {v = isetoid (flip Elem _)}
- {a = projectAlgebra a _}
- (a.varFunc _)
- (bindHomo (a.varFunc _))
- (\i => (a.algebra.equivalence _).reflexive)
- (index tms i)) $
- (a.algebra.equivalence _).symmetric $
- (a.algebra.equivalence _).transitive
- (a.algebra.substVarL ctx i _) $
- (a.algebra.equivalence _).equalImpliesEq $
- indexMap {f = \t => bindTerm {a = project a.raw ctx} (\_ => a.raw.var)} tms i)
- tm)
+ CalcWith (pwSetoid (a.setoid.reindex (\ty => (snd ty, fst ty ++ ctx))) _) $
+ |~ wrap (MkPair []) (bindTerms {a = project a.raw ctx} (\_ => a.raw.var) _ (unwrap (MkPair []) tms))
+ ~~ wrap (MkPair []) (map (\t => fromInitial a.raw t ctx) (unwrap (MkPair []) tms))
+ .=.(cong (wrap _) $ bindTermsIsMap {a = project a.raw ctx} _ _)
+ ~~ wrap (MkPair []) (unwrap (MkPair []) (map (extendFunc (fromInitial a.raw) ctx) tms))
+ .=.(cong (wrap _) $ mapUnwrap (MkPair []) tms)
+ ~~ map (extendFunc (fromInitial a.raw) ctx) tms
+ .=.(wrapUnwrap _)
+ , varHomo = \_ => (a.algebra.equivalence _).reflexive
+ , substHomo = \t, ctx, tm, tms =>
+ bindUnique'
+ {v = isetoid (flip Elem _)}
+ {a = projectAlgebra a _}
+ (compHomo
+ (bindHomo (a.varFunc _))
+ (bindHomo (indexFunc tms)))
+ (compHomo
+ (a.substHomo1 ctx _) (bindHomo (a.varFunc _)))
+ (\i => CalcWith (a.setoid.index _) $
+ |~ bindTerm {a = project a.raw _} (\_ => a.raw.var) _ (index tms i)
+ ~~ index (map (bindTerm {a = project a.raw _} (\_ => a.raw.var)) tms) i
+ .=<(indexMap {f = bindTerm {a = project a.raw _} (\_ => a.raw.var)} tms i)
+ ~~ a.raw.subst _ ctx (a.raw.var i) (map (bindTerm {a = project a.raw _} (\_ => a.raw.var)) tms)
+ ..<(a.algebra.substVarL ctx i _))
+ tm
+ }
public export
fromInitialHomo : (a : SecondOrder.Algebra.Algebra (lift sig))
@@ -358,5 +347,135 @@ fromInitialUnique {sig = sig} {a = a} f t ctx = bindUnique
{v = isetoid (flip Elem _)}
{a = projectAlgebra a ctx}
(a.varFunc ctx)
- (compHomo (projectHomo f ctx) (freeToInitialHomo sig ctx))
+ (compHomo (projectHomo f ctx) (ProjectInitialIsFree sig ctx).to)
f.homo.varHomo
+
+public export
+FreeExtension : RawAlgebra sig -> RawAlgebra (lift sig)
+FreeExtension a = MakeRawAlgebra
+ { U = \t, ctx => (FreeExtension a (flip Elem ctx)).U t
+ , rename = \t, f => extend (\_ => curry f) t
+ , sem = \ctx, (MkOp (Op op)) => Call (MkOp op) . unwrap (MkPair [])
+ , var = Done . Right . Done
+ , subst = \t, ctx, tm, tms =>
+ coproduct
+ {z = FreeExtension a (flip Elem _)}
+ (\_ => Done . Left)
+ (bindTerm {a = FreeExtension a (flip Elem _)} (\_ => index tms))
+ t
+ tm
+ }
+
+public export
+FreeExtensionAlgebra : Algebra sig -> Algebra (lift sig)
+FreeExtensionAlgebra a = MkAlgebra
+ { raw = FreeExtension a.raw
+ , relation = \(t, ctx) => (FreeExtensionAlgebra a (isetoid (flip Elem ctx))).relation t
+ , algebra = MkIsAlgebra
+ { equivalence = \(t, ctx) => (FreeExtensionAlgebra a (isetoid (flip Elem ctx))).algebra.equivalence t
+ , renameCong = \t, f => extendCong (ifunc (\_ => curry f)) t
+ , semCong = \_ , (MkOp (Op op)) => Call (MkOp op) . unwrapIntro
+ , substCong = \t, ctx, eq, eqs => coproductCong' {z = FreeExtensionAlgebra a (isetoid (flip Elem ctx))}
+ (injectLHomo {y = FreeAlgebra (isetoid (flip Elem ctx))})
+ (injectLHomo {y = FreeAlgebra (isetoid (flip Elem ctx))})
+ (bindHomo (indexFunc _))
+ (bindHomo (indexFunc _))
+ (\_ => DoneL)
+ (bindTermCong' {a = FreeExtensionAlgebra a (isetoid (flip Elem _))} (\_, Refl => index eqs _))
+ t
+ eq
+ , renameId = \t, ctx, tm =>
+ (((FreeExtensionAlgebra a (isetoid (flip Elem _)))).algebra.equivalence _).symmetric $
+ extendUnique
+ { v = isetoid (flip Elem _)
+ , u = isetoid (flip Elem _)
+ , f = ifunc ?f -- (\_ => curry reflexive)
+ , g = idHomo
+ , congL = ?congL
+ , congR = ?congR
+ , tm = ?tm
+ }
+ -- extendUnique (ifunc (\_ => curry reflexive)) idHomo ?congL ?congR tm
+ , renameComp = \t, f, g, tm => ?renameComp
+ , semNat = \f, (MkOp (Op op)), tms => Call (MkOp op) $ ?semNat
+ , varNat = \f, i => (((FreeExtensionAlgebra a (isetoid (flip Elem _)))).algebra.equivalence _).reflexive
+ , substNat = \t, f, tm, tms => ?substNat
+ , substExnat = \t, ctx, f, tm, tms => ?substExnat
+ , substComm = \t, ctx, tm, tms, tms' => ?substComm
+ , substVarL = \ctx, i, tms => ?substVarL
+ , substVarR = \t, ctx, tm => ?substVarR
+ , substCompat = \ctx, (MkOp (Op op)), tms, tms' => Call (MkOp op) $ ?substCompat
+ }
+ }
+
+public export
+ProjectFreeExtensionIsOriginal : (a : FirstOrder.Algebra.Algebra sig)
+ -> Isomorphism (projectAlgebra (FreeExtensionAlgebra a) []) a
+
+public export
+FreeExtensionIsFree : (a : Algebra sig) -> (b : Algebra (lift sig))
+ -> Isomorphism (projectAlgebra b []) a
+ -> Homomorphism (FreeExtensionAlgebra a) b
+
+-- -- public export
+-- -- FreeExtension : RawAlgebra sig -> RawAlgebra (lift sig)
+-- -- FreeExtension a = MakeRawAlgebra
+-- -- { U = \t, ctx => (Coproduct a (Free (flip Elem ctx))).U t
+-- -- , rename = \t, f => coproduct
+-- -- {z = Coproduct a (Free (flip Elem _))}
+-- -- (\_ => Done . Left)
+-- -- (\t => Done . Right . (Initial sig).rename t f)
+-- -- t
+-- -- , sem = \ctx, (MkOp (Op op)) => Call (MkOp op) . unwrap (MkPair [])
+-- -- , var = Done . Right . Done
+-- -- , subst = \t, ctx, tm, tms => coproduct
+-- -- {z = Coproduct a (Free (flip Elem _))}
+-- -- (\_ => Done . Left)
+-- -- (\_ => bindTerm {a = Coproduct a (Free (flip Elem ctx))} (\_ => index tms))
+-- -- t
+-- -- tm
+-- -- }
+
+-- -- public export 0
+-- -- FreeExtensionRelation : (algebra : FirstOrder.Algebra.IsAlgebra sig a rel)
+-- -- -> IRel (uncurry (FreeExtension a).U)
+-- -- FreeExtensionRelation algebra (t, ctx) =
+-- -- (CoproductAlgebra (MkAlgebra _ _ algebra) (FreeAlgebra (isetoid (flip Elem ctx)))).relation t
+
+-- -- public export
+-- -- FreeExtensionIsAlgebra : {a : RawAlgebra sig} -> forall rel . (algebra : IsAlgebra sig a rel)
+-- -- -> IsAlgebra (lift sig) (FreeExtension a) (FreeExtensionRelation algebra)
+-- -- FreeExtensionIsAlgebra algebra = MkIsAlgebra
+-- -- { equivalence = \(t, ctx) => ?equivalence
+-- -- , renameCong = \t, f => coproductCong
+-- -- (injectLHomo (MkAlgebra _ _ algebra) (FreeAlgebra (isetoid (flip Elem _))))
+-- -- (compHomo (injectRHomo a ?y) ?g)
+-- -- -- (compHomo
+-- -- -- (injectRHomo (MkAlgebra _ _ algebra) (FreeAlgebra (isetoid (flip Elem _))))
+-- -- -- ((InitialAlgebra sig).renameHomo f))
+-- -- t
+-- -- , semCong = \ctx, (MkOp (Op op)) => Call (MkOp op) . unwrapIntro
+-- -- , substCong = \t, ctx, eq, eqs => coproductCong'
+-- -- (injectLHomo (MkAlgebra _ _ algebra) (FreeAlgebra (isetoid (flip Elem _))))
+-- -- (injectLHomo (MkAlgebra _ _ algebra) (FreeAlgebra (isetoid (flip Elem _))))
+-- -- (bindHomo (indexFunc _ _))
+-- -- (bindHomo (indexFunc _ _))
+-- -- (\_ => DoneL)
+-- -- ?rhs -- (bindTermCong' (\_ => index ?eqseqs))
+-- -- _
+-- -- ?eq
+-- -- , renameId = ?renameId
+-- -- , renameComp = ?renameComp
+-- -- , semNat = ?semNat
+-- -- , varNat = ?varNat
+-- -- , substNat = ?substNat
+-- -- , substExnat = ?substExnat
+-- -- , substComm = ?substComm
+-- -- , substVarL = ?substVarL
+-- -- , substVarR = ?substVarR
+-- -- , substCompat = ?substCompat
+-- -- }
+
+-- -- public export
+-- -- FreeExtensionAlgebra : Algebra sig -> Algebra (lift sig)
+-- -- FreeExtensionAlgebra a = MkAlgebra _ _ $ FreeExtensionIsAlgebra a.algebra