header {* Hand-in on 27 May at noon. Please rename the file and send your solution to me as Hw10_\your name\ *} theory Hw10 imports Nominal begin text {* Task 1 (easy) Below is the definition for lambda-terms and substitution. Prove the fact that if a variable, say x, is not free in a term L (that is x\L) then a subtitution does not change the term. *} atom_decl name nominal_datatype lam = Var "name" | App "lam" "lam" | Lam "\name\lam" ("Lam [_]._") consts subst :: "lam \ name \ lam \ lam" ("_[_::=_]" [100,100,100] 100) nominal_primrec "(Var x)[y::=s] = (if x=y then s else (Var x))" "(App t\<^isub>1 t\<^isub>2)[y::=s] = App (t\<^isub>1[y::=s]) (t\<^isub>2[y::=s])" "x\(y,s) \ (Lam [x].t)[y::=s] = Lam [x].(t[y::=s])" apply(finite_guess)+ apply(rule TrueI)+ apply(simp add: abs_fresh) apply(fresh_guess)+ done lemma forget: assumes a: "x\L" shows "L[x::=P] = L" using a proof (nominal_induct L avoiding: x P rule: lam.strong_induct) case (Lam y T) have fc: "y\x" "y\P" by fact+ have ih: "x\T \ T[x::=P] = T" by fact have a: "x\Lam [y].T" by fact show "(Lam [y].T)[x::=P] = Lam [y].T" text {* Task 2 (hard) Below I defined beta-reduction and proved the substitution lemma and the fresh_fact lemma. You should prove that beta-reduction is preserved under substitution. Hint: You might need, in additon to the lemmas below, the lemmas fresh_prod and fresh_atm. *} inductive "Beta" :: "lam\lam\bool" (" _ \\<^isub>\ _" [80,80] 80) where b1[intro]: "t1 \\<^isub>\ t2 \ App t1 s \\<^isub>\ App t2 s" | b2[intro]: "s1 \\<^isub>\ s2 \ App t s1 \\<^isub>\ App t s2" | b3[intro]: "t1 \\<^isub>\ t2 \ Lam [x].t1 \\<^isub>\ Lam [x].t2" | b4[intro]: "x\s \ App (Lam [x].t) s \\<^isub>\ t[x::=s]" lemma subst_eqvt[eqvt]: fixes pi::"name prm" shows "pi\(t1[x::=t2]) = (pi\t1)[(pi\x)::=(pi\t2)]" by (nominal_induct t1 avoiding: x t2 rule: lam.induct) (auto simp add: perm_bij fresh_atm fresh_bij) lemma fresh_fact: fixes z::"name" shows "\z\s; (z=y \ z\t)\ \ z\t[y::=s]" by (nominal_induct t avoiding: z y s rule: lam.induct) (auto simp add: abs_fresh fresh_prod fresh_atm) equivariance Beta nominal_inductive Beta by (auto simp add: abs_fresh fresh_fact) lemma substitution_lemma: assumes a: "x\y" "x\u" shows "t[x::=s][y::=u] = t[y::=u][x::=s[y::=u]]" using a by (nominal_induct t avoiding: x y s u rule: lam.induct) (auto simp add: fresh_fact forget) lemma assumes a: "t \\<^isub>\ t'" shows "t[x::=s] \\<^isub>\ t'[x::=s]" using a proof (nominal_induct t t' avoiding: x s rule: Beta.strong_induct) oops text {* Task 3 (easy) Give detailed Isar-proofs for the following two de Morgan laws. *} lemma assumes a: "\(\x. P x)" shows "\x. \P x" oops lemma assumes a: "\x. \P x" shows "\(\x. P x)" oops text {* Task 4 (hard) Below are the definition for formulae and a provablility judgement. Next are the definitions of the functions distr and cnf, which transform a formula into a conjunction normal form. A formula is in conjuctive normal form if it is of the form (P1\*P2\*\)\*(Q1\*\)\*\\*(Z1\*\) The point of this task is to show that if a formula is provable, then so is its conjunctive normals form. Hint: You might need some of the proved lemmas. *} datatype form = Prop "string" | And "form" "form" ("_ \* _") | Or "form" "form" ("_ \* _") inductive provable :: "form set \ form \ bool" ("_ \* _") where p1[intro]: "Prop s\\ \ \ \* Prop s" |p2[intro]: "\\ \* B; \ \* C\ \ \ \* B \* C" |p3[intro]: "\ \* B \ \ \* B \* C" |p4[intro]: "\ \* C \ \ \* B \* C" lemma p2_elim[dest]: assumes a: "\ \* B \* C" shows "(\ \* B) \ (\ \* C)" using a by (cases) (simp_all) lemma p34_elim[dest]: assumes a: "\ \* B \* C" shows "(\ \* B) \ (\ \* C)" using a by (cases) (simp_all) fun distr :: "form \ form \ form" where d1: "distr (A \* B) C = (distr A C) \* (distr B C)" |d2: "distr C (A \* B) = (distr C A) \* (distr C B)" |d3: "distr A B = A \* B" fun cnf :: "form \ form" where c1: "cnf (Prop s) = Prop s" |c2: "cnf (A \* B) = (cnf A) \* (cnf B)" |c3: "cnf (A \* B) = distr (cnf A) (cnf B)" thm distr.simps[no_vars] thm distr.induct[no_vars] lemma a1: assumes a: "\ \* B" shows "\ \* distr B C" using a by (induct B C rule: distr.induct) (auto) lemma a2: assumes a: "\ \* C" shows "\ \* distr B C" using a by (induct B C rule: distr.induct) (auto) lemma assumes a: "\ \* B" shows "\ \* cnf B" using a oops text {* Task 5 (?) One is also interested in the other direction of the above lemma, that is if a conjunctive normalform is provale then so is the corresponding formula. Here the induction needs to be done via an induction over the functions definition (we have not seen this principle in the lectures). Hint: The cases in this induction are just called 1 2 and 3. *} thm cnf.induct lemma a3: assumes a: "\ \* distr B C" shows "(\ \* B) \ (\ \* C)" using a by (induct B C rule: distr.induct) (auto) lemma assumes a: "\ \* cnf B" shows "\ \* B" using a proof (induct B rule: cnf.induct) print_cases oops end