chapter SeCaV (* Author: Jørgen Villadsen, DTU Compute, 2021 Contributors: Stefan Berghofer, Asta Halkjær From, Alexander Birch Jensen & Anders Schlichtkrull *) section \Sequent Calculus Verifier (SeCaV)\ theory SeCaV imports Main begin section \Syntax: Terms / Formulas\ datatype tm = Fun nat \tm list\ | Var nat datatype fm = Pre nat \tm list\ | Imp fm fm | Dis fm fm | Con fm fm | Exi fm | Uni fm | Neg fm section \Semantics: Terms / Formulas\ definition \shift e v x \ \n. if n < v then e n else if n = v then x else e (n - 1)\ primrec semantics_term and semantics_list where \semantics_term e f (Var n) = e n\ | \semantics_term e f (Fun i l) = f i (semantics_list e f l)\ | \semantics_list e f [] = []\ | \semantics_list e f (t # l) = semantics_term e f t # semantics_list e f l\ primrec semantics where \semantics e f g (Pre i l) = g i (semantics_list e f l)\ | \semantics e f g (Imp p q) = (semantics e f g p \ semantics e f g q)\ | \semantics e f g (Dis p q) = (semantics e f g p \ semantics e f g q)\ | \semantics e f g (Con p q) = (semantics e f g p \ semantics e f g q)\ | \semantics e f g (Exi p) = (\x. semantics (shift e 0 x) f g p)\ | \semantics e f g (Uni p) = (\x. semantics (shift e 0 x) f g p)\ | \semantics e f g (Neg p) = (\ semantics e f g p)\ \ \Test\ corollary \semantics e f g (Imp (Pre 0 []) (Pre 0 []))\ by simp lemma \\ semantics e f g (Neg (Imp (Pre 0 []) (Pre 0 [])))\ by simp section \Auxiliary Functions\ primrec new_term and new_list where \new_term c (Var n) = True\ | \new_term c (Fun i l) = (if i = c then False else new_list c l)\ | \new_list c [] = True\ | \new_list c (t # l) = (if new_term c t then new_list c l else False)\ primrec new where \new c (Pre i l) = new_list c l\ | \new c (Imp p q) = (if new c p then new c q else False)\ | \new c (Dis p q) = (if new c p then new c q else False)\ | \new c (Con p q) = (if new c p then new c q else False)\ | \new c (Exi p) = new c p\ | \new c (Uni p) = new c p\ | \new c (Neg p) = new c p\ primrec news where \news c [] = True\ | \news c (p # z) = (if new c p then news c z else False)\ primrec inc_term and inc_list where \inc_term (Var n) = Var (n + 1)\ | \inc_term (Fun i l) = Fun i (inc_list l)\ | \inc_list [] = []\ | \inc_list (t # l) = inc_term t # inc_list l\ primrec sub_term and sub_list where \sub_term v s (Var n) = (if n < v then Var n else if n = v then s else Var (n - 1))\ | \sub_term v s (Fun i l) = Fun i (sub_list v s l)\ | \sub_list v s [] = []\ | \sub_list v s (t # l) = sub_term v s t # sub_list v s l\ primrec sub where \sub v s (Pre i l) = Pre i (sub_list v s l)\ | \sub v s (Imp p q) = Imp (sub v s p) (sub v s q)\ | \sub v s (Dis p q) = Dis (sub v s p) (sub v s q)\ | \sub v s (Con p q) = Con (sub v s p) (sub v s q)\ | \sub v s (Exi p) = Exi (sub (v + 1) (inc_term s) p)\ | \sub v s (Uni p) = Uni (sub (v + 1) (inc_term s) p)\ | \sub v s (Neg p) = Neg (sub v s p)\ primrec member where \member p [] = False\ | \member p (q # z) = (if p = q then True else member p z)\ primrec ext where \ext y [] = True\ | \ext y (p # z) = (if member p y then ext y z else False)\ \ \Simplifications\ lemma member [iff]: \member p z \ p \ set z\ by (induct z) simp_all lemma ext [iff]: \ext y z \ set z \ set y\ by (induct z) simp_all section \Sequent Calculus\ inductive sequent_calculus (\\ _\ 0) where \\ p # z\ if \member (Neg p) z\ | \\ Dis p q # z\ if \\ p # q # z\ | \\ Imp p q # z\ if \\ Neg p # q # z\ | \\ Neg (Con p q) # z\ if \\ Neg p # Neg q # z\ | \\ Con p q # z\ if \\ p # z\ and \\ q # z\ | \\ Neg (Imp p q) # z\ if \\ p # z\ and \\ Neg q # z\ | \\ Neg (Dis p q) # z\ if \\ Neg p # z\ and \\ Neg q # z\ | \\ Exi p # z\ if \\ sub 0 t p # z\ | \\ Neg (Uni p) # z\ if \\ Neg (sub 0 t p) # z\ | \\ Uni p # z\ if \\ sub 0 (Fun i []) p # z\ and \news i (p # z)\ | \\ Neg (Exi p) # z\ if \\ Neg (sub 0 (Fun i []) p) # z\ and \news i (p # z)\ | \\ Neg (Neg p) # z\ if \\ p # z\ | \\ y\ if \\ z\ and \ext y z\ \ \Test\ corollary \\ [Imp (Pre 0 []) (Pre 0 [])]\ using sequent_calculus.intros(1,3,13) ext.simps member.simps(2) by metis section \Shorthands\ lemmas Basic = sequent_calculus.intros(1) lemmas AlphaDis = sequent_calculus.intros(2) lemmas AlphaImp = sequent_calculus.intros(3) lemmas AlphaCon = sequent_calculus.intros(4) lemmas BetaCon = sequent_calculus.intros(5) lemmas BetaImp = sequent_calculus.intros(6) lemmas BetaDis = sequent_calculus.intros(7) lemmas GammaExi = sequent_calculus.intros(8) lemmas GammaUni = sequent_calculus.intros(9) lemmas DeltaUni = sequent_calculus.intros(10) lemmas DeltaExi = sequent_calculus.intros(11) lemmas NegNeg = sequent_calculus.intros(12) lemmas Ext = sequent_calculus.intros(13) \ \Test\ lemma \\ [ Imp (Pre 0 []) (Pre 0 []) ] \ proof - from AlphaImp have ?thesis if \\ [ Neg (Pre 0 []), Pre 0 [] ] \ using that by simp with Ext have ?thesis if \\ [ Pre 0 [], Neg (Pre 0 []) ] \ using that by simp with Basic show ?thesis by simp qed section \Appendix: Soundness\ subsection \Increment Function\ primrec liftt :: \tm \ tm\ and liftts :: \tm list \ tm list\ where \liftt (Var i) = Var (Suc i)\ | \liftt (Fun a ts) = Fun a (liftts ts)\ | \liftts [] = []\ | \liftts (t # ts) = liftt t # liftts ts\ subsection \Parameters: Terms\ primrec paramst :: \tm \ nat set\ and paramsts :: \tm list \ nat set\ where \paramst (Var n) = {}\ | \paramst (Fun a ts) = {a} \ paramsts ts\ | \paramsts [] = {}\ | \paramsts (t # ts) = (paramst t \ paramsts ts)\ lemma p0 [simp]: \paramsts ts = \(set (map paramst ts))\ by (induct ts) simp_all primrec paramst' :: \tm \ nat set\ where \paramst' (Var n) = {}\ | \paramst' (Fun a ts) = {a} \ \(set (map paramst' ts))\ lemma p1 [simp]: \paramst' t = paramst t\ by (induct t) simp_all subsection \Parameters: Formulas\ primrec params :: \fm \ nat set\ where \params (Pre b ts) = paramsts ts\ | \params (Imp p q) = params p \ params q\ | \params (Dis p q) = params p \ params q\ | \params (Con p q) = params p \ params q\ | \params (Exi p) = params p\ | \params (Uni p) = params p\ | \params (Neg p) = params p\ primrec params' :: \fm \ nat set\ where \params' (Pre b ts) = \(set (map paramst' ts))\ | \params' (Imp p q) = params' p \ params' q\ | \params' (Dis p q) = params' p \ params' q\ | \params' (Con p q) = params' p \ params' q\ | \params' (Exi p) = params' p\ | \params' (Uni p) = params' p\ | \params' (Neg p) = params' p\ lemma p2 [simp]: \params' p = params p\ by (induct p) simp_all fun paramst'' :: \tm \ nat set\ where \paramst'' (Var n) = {}\ | \paramst'' (Fun a ts) = {a} \ (\t \ set ts. paramst'' t)\ lemma p1' [simp]: \paramst'' t = paramst t\ by (induct t) simp_all fun params'' :: \fm \ nat set\ where \params'' (Pre b ts) = (\t \ set ts. paramst'' t)\ | \params'' (Imp p q) = params'' p \ params'' q\ | \params'' (Dis p q) = params'' p \ params'' q\ | \params'' (Con p q) = params'' p \ params'' q\ | \params'' (Exi p) = params'' p\ | \params'' (Uni p) = params'' p\ | \params'' (Neg p) = params'' p\ lemma p2' [simp]: \params'' p = params p\ by (induct p) simp_all subsection \Update Lemmas\ lemma upd_lemma' [simp]: \n \ paramst t \ semantics_term e (f(n := z)) t = semantics_term e f t\ \n \ paramsts ts \ semantics_list e (f(n := z)) ts = semantics_list e f ts\ by (induct t and ts rule: paramst.induct paramsts.induct) auto lemma upd_lemma [iff]: \n \ params p \ semantics e (f(n := z)) g p \ semantics e f g p\ by (induct p arbitrary: e) simp_all subsection \Substitution\ primrec substt :: \tm \ tm \ nat \ tm\ and substts :: \tm list \ tm \ nat \ tm list\ where \substt (Var i) s k = (if k < i then Var (i - 1) else if i = k then s else Var i)\ | \substt (Fun a ts) s k = Fun a (substts ts s k)\ | \substts [] s k = []\ | \substts (t # ts) s k = substt t s k # substts ts s k\ primrec subst :: \fm \ tm \ nat \ fm\ where \subst (Pre b ts) s k = Pre b (substts ts s k)\ | \subst (Imp p q) s k = Imp (subst p s k) (subst q s k)\ | \subst (Dis p q) s k = Dis (subst p s k) (subst q s k)\ | \subst (Con p q) s k = Con (subst p s k) (subst q s k)\ | \subst (Exi p) s k = Exi (subst p (liftt s) (Suc k))\ | \subst (Uni p) s k = Uni (subst p (liftt s) (Suc k))\ | \subst (Neg p) s k = Neg (subst p s k)\ lemma shift_eq [simp]: \i = j \ (shift e i T) j = T\ for i :: nat unfolding shift_def by simp lemma shift_gt [simp]: \j < i \ (shift e i T) j = e j\ for i :: nat unfolding shift_def by simp lemma shift_lt [simp]: \i < j \ (shift e i T) j = e (j - 1)\ for i :: nat unfolding shift_def by simp lemma shift_commute [simp]: \shift (shift e i U) 0 T = shift (shift e 0 T) (Suc i) U\ unfolding shift_def by force lemma subst_lemma' [simp]: \semantics_term e f (substt t u i) = semantics_term (shift e i (semantics_term e f u)) f t\ \semantics_list e f (substts ts u i) = semantics_list (shift e i (semantics_term e f u)) f ts\ by (induct t and ts rule: substt.induct substts.induct) simp_all lemma lift_lemma [simp]: \semantics_term (shift e 0 x) f (liftt t) = semantics_term e f t\ \semantics_list (shift e 0 x) f (liftts ts) = semantics_list e f ts\ by (induct t and ts rule: liftt.induct liftts.induct) simp_all lemma subst_lemma [iff]: \semantics e f g (subst a t i) \ semantics (shift e i (semantics_term e f t)) f g a\ by (induct a arbitrary: e i t) simp_all subsection \Auxiliary Lemmas\ lemma s1 [iff]: \new_term c t \ (c \ paramst t)\ \new_list c l \ (c \ paramsts l)\ by (induct t and l rule: new_term.induct new_list.induct) simp_all lemma s2 [iff]: \new c p \ (c \ params p)\ by (induct p) simp_all lemma s3 [iff]: \news c z \ list_all (\p. c \ params p) z\ by (induct z) simp_all lemma s4 [simp]: \inc_term t = liftt t\ \inc_list l = liftts l\ by (induct t and l rule: inc_term.induct inc_list.induct) simp_all lemma s5 [simp]: \sub_term v s t = substt t s v\ \sub_list v s l = substts l s v\ by (induct t and l rule: inc_term.induct inc_list.induct) simp_all lemma s6 [simp]: \sub v s p = subst p s v\ by (induct p arbitrary: v s) simp_all subsection \Soundness\ theorem sound: \\ z \ \p \ set z. semantics e f g p\ proof (induct arbitrary: f rule: sequent_calculus.induct) case (10 i p z) then show ?case proof (cases \\x. semantics e (f(i := \_. x)) g (sub 0 (Fun i []) p)\) case False moreover have \list_all (\p. i \ params p) z\ using 10 by simp ultimately show ?thesis using 10 Ball_set insert_iff list.set(2) upd_lemma by metis qed simp next case (11 i p z) then show ?case proof (cases \\x. semantics e (f(i := \_. x)) g (Neg (sub 0 (Fun i []) p))\) case False moreover have \list_all (\p. i \ params p) z\ using 11 by simp ultimately show ?thesis using 11 Ball_set insert_iff list.set(2) upd_lemma by metis qed simp qed force+ corollary \\ z \ \p. member p z \ semantics e f g p\ using sound by force corollary \\ [p] \ semantics e f g p\ using sound by force corollary \\ (\ [])\ using sound by force section \Reference\ text \Mordechai Ben-Ari (Springer 2012): Mathematical Logic for Computer Science (Third Edition)\ end