\import Algebra.Meta \import Data.Bool \import Data.Or \import Homotopy.Fibration \import Logic \import Logic.Classical \import Logic.FirstOrder.Term \import Logic.Meta \import Paths \import Paths.Meta \import Set.Fin \class Signature \extends TermSig | PredSymb : \Set | predDomain : PredSymb -> Array Sort \data Formula {S : Signature} (V : S -> \Set) | equality {s : S} (Term V s) (Term V s) | predicate (P : PredSymb) (DArray (\lam j => Term V (predDomain P j))) \func substF {S : Signature} {U V : S -> \Set} (phi : Formula U) (rho : \Pi {s : S} -> U s -> Term V s) : Formula V \elim phi | equality t1 t2 => equality (subst t1 rho) (subst t2 rho) | predicate P ts => predicate P (\lam j => subst (ts j) rho) \func Sequent {S : Signature} => \Sigma (V : S -> \Set) (FinSet (\Sigma (s : S) (V s))) (Array (Formula V)) (Formula V) \class Theory \extends Signature { | axioms : Sequent -> \Prop \truncated \data isTheorem {V : Sort -> \Set} (phi : Array (Formula V)) (psi : Formula V) : \Prop \elim psi | equality a b => refl (a = b) | psi => { | proj (j : Fin phi.len) (psi = phi j) | substPres (U : Sort -> \Set) (chi : Formula U) (rho rho' : \Pi {s : Sort} -> U s -> Term V s) (\Pi {s : Sort} (u : U s) -> isTheorem phi (equality (rho u) (rho' u))) (isTheorem phi (substF chi rho)) (psi = substF chi rho') | axiom (a : Sequent) (axioms a) (rho : \Pi {s : Sort} -> a.1 s -> Term V s) (∀ (chi : a.3) (isTheorem phi (substF chi rho))) (psi = substF a.4 rho) } \lemma congruence {V : Sort -> \Set} {phi : Array (Formula V)} {s : Sort} {f : Symb s} {l l' : DArray (\lam j => Term V (domain f j))} (e : \Pi (j : Fin (DArray.len {domain f})) -> isTheorem phi (equality (l j) (l' j))) : isTheorem phi (equality (apply f l) (apply f l')) => substPres (\lam s => Or (V s) (Given (s' : domain f) (s = s'))) (equality (subst (apply f l) (\lam v => var (inl v))) (apply f (\lam j => var (inr (j,idp))))) (\case __ \with { | inl v => var v | inr (j,p) => rewrite p (l j) }) (\case __ \with { | inl v => var v | inr (j,p) => rewrite p (l' j) }) (\lam {s'} u => \case \elim s', \elim u \with { | _, inl v => refl idp | _, inr (j,idp) => e j }) (transportInv (\lam x => isTheorem phi (equality (apply f x) (apply f l))) (exts (\lam j => subst-assoc (l j) _ _ *> subst_var (l j))) (refl idp)) (cong (exts (\lam j => inv (subst-assoc (l j) _ _ *> subst_var (l j))))) \lemma congruenceF {V : Sort -> \Set} {phi : Array (Formula V)} {P : PredSymb} {l l' : DArray (\lam j => Term V (predDomain P j))} (e : \Pi (j : Fin (DArray.len {predDomain P})) -> isTheorem phi (equality (l j) (l' j))) (th : isTheorem phi (predicate P l)) : isTheorem phi (predicate P l') => substPres (\lam s => Given (s' : predDomain P) (s = s')) (predicate P (\lam j => var (j,idp))) (\lam q => rewrite q.2 (l q.1)) (\lam q => rewrite q.2 (l' q.1)) (\lam {s'} q => \case \elim s', \elim q \with { | _, (j,idp) => e j }) th idp \lemma symmetry {V : Sort -> \Set} {phi : Array (Formula V)} {s : Sort} {t t' : Term V s} (p : isTheorem phi (equality t t')) : isTheorem phi (equality t' t) => substPres (\lam s' => \Sigma (s' = s) Bool) (equality (var (idp,true)) (var (idp,false))) (\lam q => rewrite q.1 t) (\lam q => rewrite q.1 (if q.2 t' t)) (\lam {s'} => \case \elim s', \elim __ \with { | _, (idp,true) => p | _, (idp,false) => refl idp }) (refl idp) idp \lemma transitivity {V : Sort -> \Set} {phi : Array (Formula V)} {s : Sort} {t1 t2 t3 : Term V s} (p1 : isTheorem phi (equality t1 t2)) (p2 : isTheorem phi (equality t2 t3)) : isTheorem phi (equality t1 t3) => substPres (\lam s' => \Sigma (s' = s) Bool) (equality (var (idp,true)) (var (idp,false))) (\lam q => rewrite q.1 (if q.2 t1 t2)) (\lam q => rewrite q.1 (if q.2 t1 t3)) (\lam {s'} => \case \elim s', \elim __ \with { | _, (idp,true) => refl idp | _, (idp,false) => p2 }) p1 idp \truncated \data QTerm (s : Sort) : \Set | qinj (Term (\lam _ => Empty) s) | qapply (f : Symb s) (DArray (\lam j => QTerm (domain f j))) | qquot {t t' : Term (\lam _ => Empty) s} (isTheorem nil (equality t t')) : qinj t = qinj t' | qmerge {f : Symb s} (ds : DArray (\lam j => Term (\lam _ => Empty) (domain f j))) : qinj (apply f ds) = qapply f (\new DArray { | at j => qinj (ds j) }) \func qinj-surj {s : Sort} (q : QTerm s) : TruncP (Fib qinj q) \elim q | qinj t => inP (t, idp) | qapply f d => TruncP.map (choice (\lam j => qinj-surj (d j))) (\lam g => (apply f (\lam j => (g j).1), path (qmerge _) *> pmap (\lam x => qapply f (\new DArray (\lam j => QTerm (domain f j)) x)) (ext (\lam j => (g j).2)))) \lemma qinj-equality {s : Sort} {t t' : Term (\lam _ => Empty) s} : (qinj t = qinj t') = isTheorem nil (equality t t') => propExt (transport (code t) __ (refl idp)) (\lam p => path (qquot p)) \where { \func code {s : Sort} (t : Term (\lam _ => Empty) s) (q : QTerm s) : \Prop \elim q | qinj t' => isTheorem nil (equality t t') | qapply f d => \Pi (d' : DArray (\lam j => Term (\lam _ => Empty) (domain f j))) -> (\Pi (j : Fin (DArray.len {domain f})) -> code (d' j) (d j)) -> isTheorem nil (equality t (apply f d')) | qquot {t1} {t2} p => ext (transitivity __ p, transitivity __ (symmetry p)) | qmerge {f} ds => ext (\lam t~fds ds' ds'~ds => transitivity t~fds (symmetry (congruence ds'~ds)), \lam g => g ds (\lam j => refl idp)) } \truncated \data isPartialTheorem (seq : Sequent) : \Prop \with | (_, _, _, equality (var v) (var v')) => varDef (v = v') | (V, vf, phi, equality a b) => sym (isTheorem phi (equality b a)) | (V, vf, phi : Array, psi) => { | partProj (j : Fin phi.len) (psi = phi j) | partSubstPres {U : Sort -> \Set} (chi : Formula U) (rho rho' : \Pi {s : Sort} -> U s -> Term V s) (\Pi {s : Sort} (u : U s) -> isTheorem phi (equality (rho u) (rho' u))) (isTheorem phi (substF chi rho)) (psi = substF chi rho') | predDef (P : PredSymb) (ts : DArray (\lam j => Term V (predDomain P j))) (isTheorem phi (predicate P ts)) (Given (t : ts) (psi = equality t t)) | funcDef {s : Sort} (h : Symb s) (ts : DArray (\lam j => Term V (domain h j))) (isTheorem phi (equality (apply h ts) (apply h ts))) (Given (t : ts) (psi = equality t t)) | partAxiom (a : Sequent) (axioms a) (rho : \Pi {s : Sort} -> a.1 s -> Term V s) (\Pi {s : Sort} (v : a.1 s) -> isTheorem phi (equality (rho v) (rho v))) (∀ (chi : a.3) (isTheorem phi (substF chi rho))) (psi = substF a.4 rho) } } \class Structure (T : Signature) (\classifying E : Sort -> \Set) { | operation {r : Sort} (h : Symb r) : DArray (\lam j => E (domain h j)) -> E r | relation (P : PredSymb) : DArray (\lam j => E (predDomain P j)) -> \Prop \func Env (V : Sort -> \Set) => \Pi {s : Sort} -> V s -> E s \func interpret {V : Sort -> \Set} (rho : Env V) {s : Sort} (t : Term V s) : E s \elim t | var v => rho v | apply f d => operation f (\lam j => interpret rho (d j)) \lemma subst_interpret {U V : Sort -> \Set} {rho : Env V} {tau : \Pi {s : T} -> U s -> Term V s} {s : Sort} (t : Term U s) : interpret rho (subst t tau) = interpret (\lam u => interpret rho (tau u)) t \elim t | var v => idp | apply f d => cong (ext (\lam j => subst_interpret (d j))) \func isFormulaTrue {V : Sort -> \Set} (rho : Env V) (phi : Formula V) : \Prop \elim phi | equality t t' => interpret rho t = interpret rho t' | predicate P d => relation P (\lam j => interpret rho (d j)) \lemma subst_isFormulaTrue {U V : Sort -> \Set} {rho : Env V} {tau : \Pi {s : T} -> U s -> Term V s} {phi : Formula U} : isFormulaTrue rho (substF phi tau) = isFormulaTrue (\lam u => interpret rho (tau u)) phi \elim phi | equality t t' => pmap2 (=) (subst_interpret t) (subst_interpret t') | predicate P d => cong (ext (\lam j => subst_interpret (d j))) \func isSequentTrue (S : Sequent) => \Pi (rho : Env S.1) -> ∀ (phi : S.3) (isFormulaTrue rho phi) -> isFormulaTrue rho S.4 } \class Model \extends Structure { \override T : Theory | isModel (S : Sequent) : axioms {T} S -> Structure.isSequentTrue S \lemma theoremIsTrue {V : Sort -> \Set} {phis : Array (Formula V)} {psi : Formula V} (t : isTheorem phis psi) (rho : Env V) (c : ∀ (phi : phis) (isFormulaTrue rho phi)) : isFormulaTrue rho psi \elim psi, t | equality a _, refl idp => idp | psi, proj j p => rewrite p (c j) | _, substPres U chi tau1 tau2 tauE t idp => propExt.conv subst_isFormulaTrue (transport (\lam (rho : Env U) => isFormulaTrue rho chi) (ext (\lam u => theoremIsTrue (tauE u) rho c)) (propExt.dir subst_isFormulaTrue (theoremIsTrue t rho c))) | _, axiom S a tau t idp => propExt.conv subst_isFormulaTrue (isModel S a _ (\lam j => propExt.dir subst_isFormulaTrue (theoremIsTrue (t j) rho c))) \func qinterpret {s : Sort} (t : QTerm s) : E s \elim t | qinj t => interpret (\lam {_} => absurd) t | qapply f d => operation f (\lam j => qinterpret (d j)) | qquot p => theoremIsTrue p (\lam {_} => absurd) (\case __) | qmerge {f} ds _ => operation f (\new DArray _ (\lam j => interpret (\lam {_} => absurd) (ds j))) } \where \open Theory