kleing@44070: header "Semantic Equivalence up to a Condition" kleing@44070: kleing@44070: theory Sem_Equiv gerwin@48909: imports Big_Step kleing@44070: begin kleing@44070: gerwin@48909: type_synonym assn = "state \ bool" gerwin@48909: kleing@44070: definition kleing@52021: equiv_up_to :: "assn \ com \ com \ bool" ("_ \ _ \ _" [50,0,10] 50) kleing@44070: where kleing@52121: "(P \ c \ c') = (\s s'. P s \ (c,s) \ s' \ (c',s) \ s')" kleing@44070: gerwin@48909: definition kleing@52021: bequiv_up_to :: "assn \ bexp \ bexp \ bool" ("_ \ _ <\> _" [50,0,10] 50) gerwin@48909: where kleing@52121: "(P \ b <\> b') = (\s. P s \ bval b s = bval b' s)" kleing@44070: kleing@44070: lemma equiv_up_to_True: kleing@44070: "((\_. True) \ c \ c') = (c \ c')" kleing@44070: by (simp add: equiv_def equiv_up_to_def) kleing@44070: kleing@44070: lemma equiv_up_to_weaken: kleing@44070: "P \ c \ c' \ (\s. P' s \ P s) \ P' \ c \ c'" kleing@44070: by (simp add: equiv_up_to_def) kleing@44070: kleing@44070: lemma equiv_up_toI: kleing@44070: "(\s s'. P s \ (c, s) \ s' = (c', s) \ s') \ P \ c \ c'" kleing@44070: by (unfold equiv_up_to_def) blast kleing@44070: kleing@44070: lemma equiv_up_toD1: gerwin@48909: "P \ c \ c' \ (c, s) \ s' \ P s \ (c', s) \ s'" kleing@44070: by (unfold equiv_up_to_def) blast kleing@44070: kleing@44070: lemma equiv_up_toD2: gerwin@48909: "P \ c \ c' \ (c', s) \ s' \ P s \ (c, s) \ s'" kleing@44070: by (unfold equiv_up_to_def) blast kleing@44070: kleing@44070: kleing@44070: lemma equiv_up_to_refl [simp, intro!]: kleing@44070: "P \ c \ c" kleing@44070: by (auto simp: equiv_up_to_def) kleing@44070: kleing@44070: lemma equiv_up_to_sym: kleing@44070: "(P \ c \ c') = (P \ c' \ c)" kleing@44070: by (auto simp: equiv_up_to_def) kleing@44070: kleing@45218: lemma equiv_up_to_trans: kleing@44070: "P \ c \ c' \ P \ c' \ c'' \ P \ c \ c''" kleing@44070: by (auto simp: equiv_up_to_def) kleing@44070: kleing@44070: kleing@44070: lemma bequiv_up_to_refl [simp, intro!]: kleing@44070: "P \ b <\> b" kleing@44070: by (auto simp: bequiv_up_to_def) kleing@44070: kleing@44070: lemma bequiv_up_to_sym: kleing@44070: "(P \ b <\> b') = (P \ b' <\> b)" kleing@44070: by (auto simp: bequiv_up_to_def) kleing@44070: kleing@45218: lemma bequiv_up_to_trans: kleing@44070: "P \ b <\> b' \ P \ b' <\> b'' \ P \ b <\> b''" kleing@44070: by (auto simp: bequiv_up_to_def) kleing@44070: gerwin@48909: lemma bequiv_up_to_subst: gerwin@48909: "P \ b <\> b' \ P s \ bval b s = bval b' s" gerwin@48909: by (simp add: bequiv_up_to_def) kleing@44070: kleing@44070: nipkow@47818: lemma equiv_up_to_seq: gerwin@48909: "P \ c \ c' \ Q \ d \ d' \ gerwin@48909: (\s s'. (c,s) \ s' \ P s \ Q s') \ nipkow@52046: P \ (c;; d) \ (c';; d')" gerwin@48909: by (clarsimp simp: equiv_up_to_def) blast kleing@44070: kleing@44070: lemma equiv_up_to_while_lemma: gerwin@48909: shows "(d,s) \ s' \ kleing@44070: P \ b <\> b' \ gerwin@48909: (\s. P s \ bval b s) \ c \ c' \ gerwin@48909: (\s s'. (c, s) \ s' \ P s \ bval b s \ P s') \ gerwin@48909: P s \ gerwin@48909: d = WHILE b DO c \ gerwin@48909: (WHILE b' DO c', s) \ s'" nipkow@45015: proof (induction rule: big_step_induct) kleing@44070: case (WhileTrue b s1 c s2 s3) gerwin@48909: hence IH: "P s2 \ (WHILE b' DO c', s2) \ s3" by auto kleing@44070: from WhileTrue.prems kleing@44070: have "P \ b <\> b'" by simp kleing@44070: with `bval b s1` `P s1` kleing@44070: have "bval b' s1" by (simp add: bequiv_up_to_def) kleing@44070: moreover kleing@44070: from WhileTrue.prems kleing@44070: have "(\s. P s \ bval b s) \ c \ c'" by simp kleing@44070: with `bval b s1` `P s1` `(c, s1) \ s2` kleing@44070: have "(c', s1) \ s2" by (simp add: equiv_up_to_def) kleing@44070: moreover kleing@44070: from WhileTrue.prems gerwin@48909: have "\s s'. (c,s) \ s' \ P s \ bval b s \ P s'" by simp kleing@44070: with `P s1` `bval b s1` `(c, s1) \ s2` gerwin@48909: have "P s2" by simp kleing@44070: hence "(WHILE b' DO c', s2) \ s3" by (rule IH) gerwin@48909: ultimately kleing@44070: show ?case by blast kleing@44070: next kleing@44070: case WhileFalse kleing@44070: thus ?case by (auto simp: bequiv_up_to_def) gerwin@48909: qed (fastforce simp: equiv_up_to_def bequiv_up_to_def)+ kleing@44070: kleing@44070: lemma bequiv_context_subst: kleing@44070: "P \ b <\> b' \ (P s \ bval b s) = (P s \ bval b' s)" kleing@44070: by (auto simp: bequiv_up_to_def) kleing@44070: kleing@44070: lemma equiv_up_to_while: gerwin@48909: assumes b: "P \ b <\> b'" gerwin@48909: assumes c: "(\s. P s \ bval b s) \ c \ c'" gerwin@48909: assumes I: "\s s'. (c, s) \ s' \ P s \ bval b s \ P s'" gerwin@48909: shows "P \ WHILE b DO c \ WHILE b' DO c'" gerwin@48909: proof - gerwin@48909: from b have b': "P \ b' <\> b" by (simp add: bequiv_up_to_sym) gerwin@48909: gerwin@48909: from c b have c': "(\s. P s \ bval b' s) \ c' \ c" gerwin@48909: by (simp add: equiv_up_to_sym bequiv_context_subst) gerwin@48909: gerwin@48909: from I gerwin@48909: have I': "\s s'. (c', s) \ s' \ P s \ bval b' s \ P s'" gerwin@48909: by (auto dest!: equiv_up_toD1 [OF c'] simp: bequiv_up_to_subst [OF b']) gerwin@48909: gerwin@48909: note equiv_up_to_while_lemma [OF _ b c] gerwin@48909: equiv_up_to_while_lemma [OF _ b' c'] gerwin@48909: thus ?thesis using I I' by (auto intro!: equiv_up_toI) gerwin@48909: qed kleing@44070: kleing@44070: lemma equiv_up_to_while_weak: gerwin@48909: "P \ b <\> b' \ P \ c \ c' \ gerwin@48909: (\s s'. (c, s) \ s' \ P s \ bval b s \ P s') \ kleing@44070: P \ WHILE b DO c \ WHILE b' DO c'" gerwin@48909: by (fastforce elim!: equiv_up_to_while equiv_up_to_weaken) kleing@44070: kleing@44070: lemma equiv_up_to_if: huffman@44261: "P \ b <\> b' \ (\s. P s \ bval b s) \ c \ c' \ (\s. P s \ \bval b s) \ d \ d' \ kleing@44070: P \ IF b THEN c ELSE d \ IF b' THEN c' ELSE d'" kleing@44070: by (auto simp: bequiv_up_to_def equiv_up_to_def) kleing@44070: kleing@44070: lemma equiv_up_to_if_weak: kleing@44070: "P \ b <\> b' \ P \ c \ c' \ P \ d \ d' \ kleing@44070: P \ IF b THEN c ELSE d \ IF b' THEN c' ELSE d'" nipkow@44890: by (fastforce elim!: equiv_up_to_if equiv_up_to_weaken) kleing@44070: kleing@44070: lemma equiv_up_to_if_True [intro!]: kleing@44070: "(\s. P s \ bval b s) \ P \ IF b THEN c1 ELSE c2 \ c1" gerwin@48909: by (auto simp: equiv_up_to_def) kleing@44070: kleing@44070: lemma equiv_up_to_if_False [intro!]: kleing@44070: "(\s. P s \ \ bval b s) \ P \ IF b THEN c1 ELSE c2 \ c2" kleing@44070: by (auto simp: equiv_up_to_def) kleing@44070: kleing@44070: lemma equiv_up_to_while_False [intro!]: kleing@44070: "(\s. P s \ \ bval b s) \ P \ WHILE b DO c \ SKIP" kleing@44070: by (auto simp: equiv_up_to_def) kleing@44070: nipkow@45200: lemma while_never: "(c, s) \ u \ c \ WHILE (Bc True) DO c'" kleing@44070: by (induct rule: big_step_induct) auto gerwin@48909: kleing@44070: lemma equiv_up_to_while_True [intro!,simp]: nipkow@45200: "P \ WHILE Bc True DO c \ WHILE Bc True DO SKIP" kleing@44070: unfolding equiv_up_to_def kleing@44070: by (blast dest: while_never) kleing@44070: kleing@44070: huffman@44261: end