added imperative SAT checker; improved headers of example files; adopted IsaMakefile
authorbulwahn
Thu, 08 Apr 2010 08:17:27 +0200
changeset 36098 53992c639da5
parent 36097 32383448c01b
child 36099 7e1f972df25f
added imperative SAT checker; improved headers of example files; adopted IsaMakefile
src/HOL/Imperative_HOL/Imperative_HOL_ex.thy
src/HOL/Imperative_HOL/ex/Imperative_Quicksort.thy
src/HOL/Imperative_HOL/ex/Imperative_Reverse.thy
src/HOL/Imperative_HOL/ex/Linked_Lists.thy
src/HOL/Imperative_HOL/ex/SatChecker.thy
src/HOL/Imperative_HOL/ex/Sorted_List.thy
src/HOL/Imperative_HOL/ex/Subarray.thy
src/HOL/Imperative_HOL/ex/Sublist.thy
src/HOL/IsaMakefile
--- a/src/HOL/Imperative_HOL/Imperative_HOL_ex.thy	Wed Apr 07 22:22:49 2010 +0200
+++ b/src/HOL/Imperative_HOL/Imperative_HOL_ex.thy	Thu Apr 08 08:17:27 2010 +0200
@@ -7,6 +7,7 @@
 
 theory Imperative_HOL_ex
 imports Imperative_HOL "ex/Imperative_Quicksort" "ex/Imperative_Reverse" "ex/Linked_Lists"
+  "ex/SatChecker"
 begin
 
 end
--- a/src/HOL/Imperative_HOL/ex/Imperative_Quicksort.thy	Wed Apr 07 22:22:49 2010 +0200
+++ b/src/HOL/Imperative_HOL/ex/Imperative_Quicksort.thy	Thu Apr 08 08:17:27 2010 +0200
@@ -1,4 +1,8 @@
-(* Author: Lukas Bulwahn, TU Muenchen *)
+(*  Title:      HOL/Imperative_HOL/ex/Imperative_Quicksort.thy
+    Author:     Lukas Bulwahn, TU Muenchen
+*)
+
+header {* An imperative implementation of Quicksort on arrays *}
 
 theory Imperative_Quicksort
 imports "~~/src/HOL/Imperative_HOL/Imperative_HOL" Subarray Multiset Efficient_Nat
--- a/src/HOL/Imperative_HOL/ex/Imperative_Reverse.thy	Wed Apr 07 22:22:49 2010 +0200
+++ b/src/HOL/Imperative_HOL/ex/Imperative_Reverse.thy	Thu Apr 08 08:17:27 2010 +0200
@@ -1,3 +1,9 @@
+(*  Title:      HOL/Imperative_HOL/ex/Imperative_Reverse.thy
+    Author:     Lukas Bulwahn, TU Muenchen
+*)
+
+header {* An imperative in-place reversal on arrays *}
+
 theory Imperative_Reverse
 imports "~~/src/HOL/Imperative_HOL/Imperative_HOL" Subarray
 begin
--- a/src/HOL/Imperative_HOL/ex/Linked_Lists.thy	Wed Apr 07 22:22:49 2010 +0200
+++ b/src/HOL/Imperative_HOL/ex/Linked_Lists.thy	Thu Apr 08 08:17:27 2010 +0200
@@ -1,3 +1,9 @@
+(*  Title:      HOL/Imperative_HOL/ex/Linked_Lists.thy
+    Author:     Lukas Bulwahn, TU Muenchen
+*)
+
+header {* Linked Lists by ML references *}
+
 theory Linked_Lists
 imports "~~/src/HOL/Imperative_HOL/Imperative_HOL" Code_Integer
 begin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Imperative_HOL/ex/SatChecker.thy	Thu Apr 08 08:17:27 2010 +0200
@@ -0,0 +1,680 @@
+(*  Title:      HOL/Imperative_HOL/ex/SatChecker.thy
+    Author:     Lukas Bulwahn, TU Muenchen
+*)
+
+header {* An efficient checker for proofs from a SAT solver *}
+
+theory SatChecker
+imports RBT Sorted_List "~~/src/HOL/Imperative_HOL/Imperative_HOL" 
+begin
+
+section{* General settings and functions for our representation of clauses *}
+
+subsection{* Types for Literals, Clauses and ProofSteps *}
+text {* We encode Literals as integers and Clauses as sorted Lists. *}
+
+types ClauseId = nat
+types Lit = int
+types Clause = "Lit list"
+
+text {* This resembles exactly to Isat's Proof Steps *}
+
+types Resolvants = "ClauseId * (Lit * ClauseId) list"
+datatype ProofStep =
+  ProofDone bool
+  | Root ClauseId Clause
+  | Conflict ClauseId Resolvants
+  | Delete ClauseId
+  | Xstep ClauseId ClauseId
+
+subsection{* Interpretation of Literals, Clauses, and an array of Clauses *} 
+text {* Specific definitions for Literals as integers *}
+
+definition compl :: "Lit \<Rightarrow> Lit"
+where
+  "compl a = -a"
+
+definition interpLit :: "(nat \<Rightarrow> bool) \<Rightarrow> Lit \<Rightarrow> bool"
+where
+  "interpLit assgnmt lit = (if lit > 0 then assgnmt (nat lit) else (if (lit < 0) then \<not> (assgnmt (nat (- lit))) else undefined))"
+
+lemma interpLit_compl[simp]:
+  assumes lit_not_zero: "lit \<noteq> 0"
+  shows "interpLit a (compl lit) = (\<not> interpLit a lit)"
+unfolding interpLit_def compl_def using lit_not_zero by auto
+
+lemma compl_compl_is_id[simp]:
+  "compl (compl x) = x"
+unfolding compl_def by simp
+
+lemma compl_not_zero[simp]:
+  "(compl x \<noteq> 0) = (x \<noteq> 0)"
+unfolding compl_def by simp
+
+lemma compl_exists: "\<exists>l'. l = compl l'"
+unfolding compl_def by arith
+
+text {* Specific definitions for Clauses as sorted lists *}
+
+definition interpClause :: "(nat \<Rightarrow> bool) \<Rightarrow> Clause \<Rightarrow> bool"
+where
+  "interpClause assgnmt cl = (\<exists> l \<in> set cl. interpLit assgnmt l)" 
+
+lemma interpClause_empty[simp]:
+  "interpClause a [] = False" 
+unfolding interpClause_def by simp
+
+lemma interpClause_sort[simp]: "interpClause a (sort clause) = interpClause a clause"
+unfolding interpClause_def
+by simp
+
+lemma interpClause_remdups[simp]: "interpClause a (remdups clause) = interpClause a clause"
+unfolding interpClause_def
+by simp
+
+definition 
+  "inconsistent cs = (\<forall>a.\<exists>c\<in>set cs. \<not> interpClause a c)"
+
+lemma interpClause_resolvants':
+  assumes lit_not_zero: "lit \<noteq> 0"
+  assumes resolv_clauses: "lit \<in> cli" "compl lit \<in> clj"
+  assumes interp: "\<exists>x \<in> cli. interpLit a x" "\<exists>x \<in> clj. interpLit a x"
+  shows "\<exists>x \<in> (cli - {lit} \<union> (clj - {compl lit})). interpLit a x"
+proof -
+  from resolv_clauses interp have "(\<exists>l \<in> cli - {lit}. interpLit a l) \<or> interpLit a lit"
+    "(\<exists>l \<in> clj - {compl lit}. interpLit a l) \<or> interpLit a (compl lit)" by auto
+  with lit_not_zero show ?thesis by (fastsimp simp add: bex_Un)
+qed
+
+lemma interpClause_resolvants:
+  assumes lit_not_zero: "lit \<noteq> 0"
+  assumes sorted_and_distinct: "sorted cli" "distinct cli" "sorted clj" "distinct clj"
+  assumes resolv_clauses: "lit \<in> set cli" "compl lit \<in> set clj"
+  assumes interp: "interpClause a cli" "interpClause a clj"
+  shows "interpClause a (merge (remove lit cli) (remove (compl lit) clj))"
+proof -
+  from lit_not_zero resolv_clauses interp sorted_and_distinct show ?thesis
+    unfolding interpClause_def
+    using interpClause_resolvants' by simp
+qed
+
+definition correctClause :: "Clause list \<Rightarrow> Clause \<Rightarrow> bool"
+where
+  "correctClause rootcls cl = (\<forall>a. (\<forall>rcl \<in> set rootcls. interpClause a rcl) \<longrightarrow> (interpClause a cl))"
+
+lemma correctClause_resolvants:
+  assumes lit_not_zero: "lit \<noteq> 0"
+  assumes sorted_and_distinct: "sorted cli" "distinct cli" "sorted clj" "distinct clj"
+  assumes resolv_clauses: "lit \<in> set cli" "compl lit \<in> set clj"
+  assumes correct: "correctClause r cli" "correctClause r clj"
+  shows "correctClause r (merge (remove lit cli) (remove (compl lit) clj))"
+  using assms interpClause_resolvants unfolding correctClause_def by auto
+
+
+lemma implies_empty_inconsistent: 
+  "correctClause cs [] \<Longrightarrow> inconsistent cs"
+unfolding inconsistent_def correctClause_def
+by auto
+
+text {* Specific definition for derived clauses in the Array *}
+
+definition correctArray :: "Clause list \<Rightarrow> Clause option array \<Rightarrow> heap \<Rightarrow> bool"
+where
+  "correctArray rootcls a h =
+  (\<forall>cl \<in> array_ran a h. correctClause rootcls cl \<and> sorted cl \<and> distinct cl)"
+
+lemma correctArray_update:
+  assumes "correctArray rcs a h"
+  assumes "correctClause rcs c" "sorted c" "distinct c"
+  shows "correctArray rcs a (Heap.upd a i (Some c) h)"
+  using assms
+  unfolding correctArray_def
+  by (auto dest:array_ran_upd_array_Some)
+
+lemma correctClause_mono:
+  assumes "correctClause rcs c"
+  assumes "set rcs \<subseteq> set rcs'"
+  shows "correctClause rcs' c"
+  using assms unfolding correctClause_def
+  by auto
+
+
+section{* Improved version of SatChecker *}
+
+text{* This version just uses a single list traversal. *}
+
+subsection{* Function definitions *}
+
+fun res_mem :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause Heap"
+where
+  "res_mem l [] = raise ''MiniSatChecked.res_thm: Cannot find literal''"
+| "res_mem l (x#xs) = (if (x = l) then return xs else (do v \<leftarrow> res_mem l xs; return (x # v) done))"
+
+fun resolve1 :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap"
+where
+  "resolve1 l (x#xs) (y#ys) =
+  (if (x = l) then return (merge xs (y#ys))
+  else (if (x < y) then (do v \<leftarrow> resolve1 l xs (y#ys); return (x # v) done)
+  else (if (x > y) then (do v \<leftarrow> resolve1 l (x#xs) ys; return (y # v) done)
+  else (do v \<leftarrow> resolve1 l xs ys; return (x # v) done))))"
+| "resolve1 l [] ys = raise ''MiniSatChecked.res_thm: Cannot find literal''"
+| "resolve1 l xs [] = res_mem l xs"
+
+fun resolve2 :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap" 
+where
+  "resolve2 l (x#xs) (y#ys) =
+  (if (y = l) then return (merge (x#xs) ys)
+  else (if (x < y) then (do v \<leftarrow> resolve2 l xs (y#ys); return (x # v) done)
+  else (if (x > y) then (do v \<leftarrow> resolve2 l (x#xs) ys; return (y # v) done) 
+  else (do v \<leftarrow> resolve2 l xs ys; return (x # v) done))))"
+  | "resolve2 l xs [] = raise ''MiniSatChecked.res_thm: Cannot find literal''"
+  | "resolve2 l [] ys = res_mem l ys"
+
+fun res_thm' :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap"
+where
+  "res_thm' l (x#xs) (y#ys) = 
+  (if (x = l \<or> x = compl l) then resolve2 (compl x) xs (y#ys)
+  else (if (y = l \<or> y = compl l) then resolve1 (compl y) (x#xs) ys
+  else (if (x < y) then (res_thm' l xs (y#ys)) \<guillemotright>= (\<lambda>v. return (x # v))
+  else (if (x > y) then (res_thm' l (x#xs) ys) \<guillemotright>= (\<lambda>v. return (y # v))
+  else (res_thm' l xs ys) \<guillemotright>= (\<lambda>v. return (x # v))))))"
+| "res_thm' l [] ys = raise (''MiniSatChecked.res_thm: Cannot find literal'')"
+| "res_thm' l xs [] = raise (''MiniSatChecked.res_thm: Cannot find literal'')"
+
+declare res_mem.simps [simp del] resolve1.simps [simp del] resolve2.simps [simp del] res_thm'.simps [simp del]
+
+subsection {* Proofs about these functions *}
+
+lemma res_mem:
+assumes "crel (res_mem l xs) h h' r"
+  shows "l \<in> set xs \<and> r = remove1 l xs"
+using assms
+proof (induct xs arbitrary: r)
+  case Nil
+  thus ?case unfolding res_mem.simps by (auto elim: crel_raise)
+next
+  case (Cons x xs')
+  thus ?case
+    unfolding res_mem.simps
+    by (elim crel_raise crel_return crel_if crelE) auto
+qed
+
+lemma resolve1_Inv:
+assumes "crel (resolve1 l xs ys) h h' r"
+  shows "l \<in> set xs \<and> r = merge (remove1 l xs) ys"
+using assms
+proof (induct xs ys arbitrary: r rule: resolve1.induct)
+  case (1 l x xs y ys r)
+  thus ?case
+    unfolding resolve1.simps
+    by (elim crelE crel_if crel_return) auto
+next
+  case (2 l ys r)
+  thus ?case
+    unfolding resolve1.simps
+    by (elim crel_raise) auto
+next
+  case (3 l v va r)
+  thus ?case
+    unfolding resolve1.simps
+    by (fastsimp dest!: res_mem)
+qed
+
+lemma resolve2_Inv: 
+  assumes "crel (resolve2 l xs ys) h h' r"
+  shows "l \<in> set ys \<and> r = merge xs (remove1 l ys)"
+using assms
+proof (induct xs ys arbitrary: r rule: resolve2.induct)
+  case (1 l x xs y ys r)
+  thus ?case
+    unfolding resolve2.simps
+    by (elim crelE crel_if crel_return) auto
+next
+  case (2 l ys r)
+  thus ?case
+    unfolding resolve2.simps
+    by (elim crel_raise) auto
+next
+  case (3 l v va r)
+  thus ?case
+    unfolding resolve2.simps
+    by (fastsimp dest!: res_mem simp add: merge_Nil)
+qed
+
+lemma res_thm'_Inv:
+assumes "crel (res_thm' l xs ys) h h' r"
+shows "\<exists>l'. (l' \<in> set xs \<and> compl l' \<in> set ys \<and> (l' = compl l \<or> l' = l)) \<and> r = merge (remove1 l' xs) (remove1 (compl l') ys)"
+using assms
+proof (induct xs ys arbitrary: r rule: res_thm'.induct)
+case (1 l x xs y ys r)
+(* There are five cases for res_thm: We will consider them one after another: *) 
+  {
+    assume cond: "x = l \<or> x = compl l"
+    assume resolve2: "crel (resolve2 (compl x) xs (y # ys)) h h' r"   
+    from resolve2_Inv [OF resolve2] cond have ?case
+      apply -
+      by (rule exI[of _ "x"]) fastsimp
+  } moreover
+  {
+    assume cond: "\<not> (x = l \<or> x = compl l)" "y = l \<or> y = compl l" 
+    assume resolve1: "crel (resolve1 (compl y) (x # xs) ys) h h' r"
+    from resolve1_Inv [OF resolve1] cond have ?case
+      apply -
+      by (rule exI[of _ "compl y"]) fastsimp
+  } moreover
+  {
+    fix r'
+    assume cond: "\<not> (x = l \<or> x = compl l)" "\<not> (y = l \<or> y = compl l)" "x < y"
+    assume res_thm: "crel (res_thm' l xs (y # ys)) h h' r'"
+    assume return: "r = x # r'"
+    from "1.hyps"(1) [OF cond res_thm] cond return have ?case by auto
+  } moreover
+  {
+    fix r'
+    assume cond: "\<not> (x = l \<or> x = compl l)" "\<not> (y = l \<or> y = compl l)" "\<not> x < y" "y < x"
+    assume res_thm: "crel (res_thm' l (x # xs) ys) h h' r'"
+    assume return: "r = y # r'"
+    from "1.hyps"(2) [OF cond res_thm] cond return have ?case by auto
+  } moreover
+  {
+    fix r'
+    assume cond: "\<not> (x = l \<or> x = compl l)" "\<not> (y = l \<or> y = compl l)" "\<not> x < y" "\<not> y < x"
+    assume res_thm: "crel (res_thm' l xs ys) h h' r'"
+    assume return: "r = x # r'"
+    from "1.hyps"(3) [OF cond res_thm] cond return have ?case by auto
+  } moreover
+  note "1.prems"
+  ultimately show ?case
+    unfolding res_thm'.simps
+    apply (elim crelE crel_if crel_return)
+    apply simp
+    apply simp
+    apply simp
+    apply simp
+    apply fastsimp
+    done
+next
+  case (2 l ys r)
+  thus ?case
+    unfolding res_thm'.simps
+    by (elim crel_raise) auto
+next
+  case (3 l v va r)
+  thus ?case
+    unfolding res_thm'.simps
+    by (elim crel_raise) auto
+qed
+
+lemma res_mem_no_heap:
+assumes "crel (res_mem l xs) h h' r"
+  shows "h = h'"
+using assms
+apply (induct xs arbitrary: r)
+unfolding res_mem.simps
+apply (elim crel_raise)
+apply auto
+apply (elim crel_if crelE crel_raise crel_return)
+apply auto
+done
+
+lemma resolve1_no_heap:
+assumes "crel (resolve1 l xs ys) h h' r"
+  shows "h = h'"
+using assms
+apply (induct xs ys arbitrary: r rule: resolve1.induct)
+unfolding resolve1.simps
+apply (elim crelE crel_if crel_return crel_raise)
+apply (auto simp add: res_mem_no_heap)
+by (elim crel_raise) auto
+
+lemma resolve2_no_heap:
+assumes "crel (resolve2 l xs ys) h h' r"
+  shows "h = h'"
+using assms
+apply (induct xs ys arbitrary: r rule: resolve2.induct)
+unfolding resolve2.simps
+apply (elim crelE crel_if crel_return crel_raise)
+apply (auto simp add: res_mem_no_heap)
+by (elim crel_raise) auto
+
+
+lemma res_thm'_no_heap:
+  assumes "crel (res_thm' l xs ys) h h' r"
+  shows "h = h'"
+  using assms
+proof (induct xs ys arbitrary: r rule: res_thm'.induct)
+  case (1 l x xs y ys r)
+  thus ?thesis
+    unfolding res_thm'.simps
+    by (elim crelE crel_if crel_return)
+  (auto simp add: resolve1_no_heap resolve2_no_heap)
+next
+  case (2 l ys r)
+  thus ?case
+    unfolding res_thm'.simps
+    by (elim crel_raise) auto
+next
+  case (3 l v va r)
+  thus ?case
+    unfolding res_thm'.simps
+    by (elim crel_raise) auto
+qed
+
+
+lemma res_thm'_Inv2:
+  assumes res_thm: "crel (res_thm' l xs ys) h h' rcl"
+  assumes l_not_null: "l \<noteq> 0"
+  assumes ys: "correctClause r ys \<and> sorted ys \<and> distinct ys"
+  assumes xs: "correctClause r xs \<and> sorted xs \<and> distinct xs"
+  shows "correctClause r rcl \<and> sorted rcl \<and> distinct rcl"
+proof -
+  from res_thm'_Inv [OF res_thm] xs ys l_not_null show ?thesis
+    apply (auto simp add: sorted_remove1)
+    unfolding correctClause_def
+    apply (auto simp add: remove1_eq_remove)
+    prefer 2
+    apply (rule interpClause_resolvants)
+    apply simp_all
+    apply (insert compl_exists [of l])
+    apply auto
+    apply (rule interpClause_resolvants)
+    apply simp_all
+    done
+qed
+
+subsection {* res_thm and doProofStep *}
+
+definition get_clause :: "Clause option array \<Rightarrow> ClauseId \<Rightarrow> Clause Heap"
+where
+  "get_clause a i = 
+       (do c \<leftarrow> nth a i;
+           (case c of None \<Rightarrow> raise (''Clause not found'')
+                    | Some x \<Rightarrow> return x)
+        done)"
+
+
+fun res_thm2 :: "Clause option array \<Rightarrow> (Lit * ClauseId) \<Rightarrow> Clause \<Rightarrow> Clause Heap"
+where
+  "res_thm2 a (l, j) cli =
+  ( if l = 0 then raise(''Illegal literal'')
+    else
+     (do clj \<leftarrow> get_clause a j;
+         res_thm' l cli clj
+      done))"
+
+fun doProofStep2 :: "Clause option array \<Rightarrow> ProofStep \<Rightarrow> Clause list \<Rightarrow> Clause list Heap"
+where
+  "doProofStep2 a (Conflict saveTo (i, rs)) rcs =
+  (do
+     cli \<leftarrow> get_clause a i;
+     result \<leftarrow> foldM (res_thm2 a) rs cli;
+     upd saveTo (Some result) a; 
+     return rcs
+   done)"
+| "doProofStep2 a (Delete cid) rcs = (do upd cid None a; return rcs done)"
+| "doProofStep2 a (Root cid clause) rcs = (do upd cid (Some (remdups (sort clause))) a; return (clause # rcs) done)"
+| "doProofStep2 a (Xstep cid1 cid2) rcs = raise ''MiniSatChecked.doProofStep: Xstep constructor found.''"
+| "doProofStep2 a (ProofDone b) rcs = raise ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
+
+definition checker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
+where
+  "checker n p i =
+  (do 
+     a \<leftarrow> Array.new n None;
+     rcs \<leftarrow> foldM (doProofStep2 a) p [];
+     ec \<leftarrow> Array.nth a i;
+     (if ec = Some [] then return rcs 
+                else raise(''No empty clause''))
+   done)"
+
+lemma res_thm2_Inv:
+  assumes res_thm: "crel (res_thm2 a (l, j) cli) h h' rs"
+  assumes correct_a: "correctArray r a h"
+  assumes correct_cli: "correctClause r cli \<and> sorted cli \<and> distinct cli"
+  shows "h = h' \<and> correctClause r rs \<and> sorted rs \<and> distinct rs"
+proof -
+  from res_thm have l_not_zero: "l \<noteq> 0" 
+    by (auto elim: crel_raise)
+  {
+    fix clj
+    let ?rs = "merge (remove l cli) (remove (compl l) clj)"
+    let ?rs' = "merge (remove (compl l) cli) (remove l clj)"
+    assume "h = h'" "Some clj = get_array a h' ! j" "j < Heap.length a h'"
+    with correct_a have clj: "correctClause r clj" "sorted clj" "distinct clj"
+      unfolding correctArray_def by (auto intro: array_ranI)
+    with clj l_not_zero correct_cli
+    have "(l \<in> set cli \<and> compl l \<in> set clj
+      \<longrightarrow> correctClause r ?rs \<and> sorted ?rs \<and> distinct ?rs) \<and>
+      (compl l \<in> set cli \<and> l \<in> set clj
+      \<longrightarrow> correctClause r ?rs' \<and> sorted ?rs' \<and> distinct ?rs')"
+      apply (auto intro!: correctClause_resolvants)
+      apply (insert compl_exists [of l])
+      by (auto intro!: correctClause_resolvants)
+  }
+  {
+    fix v clj
+    assume "Some clj = get_array a h ! j" "j < Heap.length a h"
+    with correct_a have clj: "correctClause r clj \<and> sorted clj \<and> distinct clj"
+      unfolding correctArray_def by (auto intro: array_ranI)
+    assume "crel (res_thm' l cli clj) h h' rs"
+    from res_thm'_no_heap[OF this] res_thm'_Inv2[OF this l_not_zero clj correct_cli]
+    have "h = h' \<and> correctClause r rs \<and> sorted rs \<and> distinct rs" by simp
+  }
+  with assms show ?thesis
+    unfolding res_thm2.simps get_clause_def
+    by (elim crelE crelE' crel_if crel_nth crel_raise crel_return crel_option_case) auto
+qed
+
+lemma foldM_Inv2:
+  assumes "crel (foldM (res_thm2 a) rs cli) h h' rcl"
+  assumes correct_a: "correctArray r a h"
+  assumes correct_cli: "correctClause r cli \<and> sorted cli \<and> distinct cli"
+  shows "h = h' \<and> correctClause r rcl \<and> sorted rcl \<and> distinct rcl"
+using assms
+proof (induct rs arbitrary: h h' cli)
+  case Nil thus ?case
+    unfolding foldM.simps
+    by (elim crel_return) auto
+next
+  case (Cons x xs)
+  {
+    fix h1 ret
+    obtain l j where x_is: "x = (l, j)" by fastsimp
+    assume res_thm2: "crel (res_thm2 a x cli) h h1 ret"
+    with x_is have res_thm2': "crel (res_thm2 a (l, j) cli) h h1 ret" by simp
+    note step = res_thm2_Inv [OF res_thm2' Cons.prems(2) Cons.prems(3)]
+    from step have ret: "correctClause r ret \<and> sorted ret \<and> distinct ret" by simp
+    from step Cons.prems(2) have correct_a: "correctArray r a h1"  by simp
+    assume foldM: "crel (foldM (res_thm2 a) xs ret) h1 h' rcl"
+    from step Cons.hyps [OF foldM correct_a ret] have
+    "h = h' \<and> correctClause r rcl \<and> sorted rcl \<and> distinct rcl" by auto
+  }
+  with Cons show ?case
+    unfolding foldM.simps
+    by (elim crelE) auto
+qed
+
+
+lemma step_correct2:
+  assumes crel: "crel (doProofStep2 a step rcs) h h' res"
+  assumes correctArray: "correctArray rcs a h"
+  shows "correctArray res a h'"
+proof (cases "(a,step,rcs)" rule: doProofStep2.cases)
+  case (1 a saveTo i rs rcs)
+  with crel correctArray
+  show ?thesis
+    apply auto
+    apply (auto simp: get_clause_def elim!: crelE crel_nth)
+    apply (auto elim!: crelE crel_nth crel_option_case crel_raise 
+      crel_return crel_upd)
+    apply (frule foldM_Inv2)
+    apply assumption
+    apply (simp add: correctArray_def)
+    apply (drule_tac x="y" in bspec)
+    apply (rule array_ranI[where i=i])
+    by (auto intro: correctArray_update)
+next
+  case (2 a cid rcs)
+  with crel correctArray
+  show ?thesis
+    by (auto simp: correctArray_def elim!: crelE crel_upd crel_return
+     dest: array_ran_upd_array_None)
+next
+  case (3 a cid c rcs)
+  with crel correctArray
+  show ?thesis
+    apply (auto elim!: crelE crel_upd crel_return)
+    apply (auto simp: correctArray_def dest!: array_ran_upd_array_Some)
+    apply (auto intro: correctClause_mono)
+    by (auto simp: correctClause_def)
+next
+  case 4
+  with crel correctArray
+  show ?thesis by (auto elim: crel_raise)
+next
+  case 5
+  with crel correctArray
+  show ?thesis by (auto elim: crel_raise)
+qed
+  
+
+theorem fold_steps_correct:
+  assumes "crel (foldM (doProofStep2 a) steps rcs) h h' res"
+  assumes "correctArray rcs a h"
+  shows "correctArray res a h'"
+using assms
+by (induct steps arbitrary: rcs h h' res)
+ (auto elim!: crelE crel_return dest:step_correct2)
+
+theorem checker_soundness:
+  assumes "crel (checker n p i) h h' cs"
+  shows "inconsistent cs"
+using assms unfolding checker_def
+apply (elim crelE crel_nth crel_if crel_return crel_raise crel_new_weak)
+prefer 2 apply simp
+apply auto
+apply (drule fold_steps_correct)
+apply (simp add: correctArray_def array_ran_def)
+apply (cases "n = 0", auto)
+apply (rule implies_empty_inconsistent)
+apply (simp add:correctArray_def)
+apply (drule bspec)
+by (rule array_ranI, auto)
+
+section {* Functional version with Lists as Array *}
+
+subsection {* List specific definitions *}
+
+definition list_ran :: "'a option list \<Rightarrow> 'a set"
+where
+  "list_ran xs = {e. Some e \<in> set xs }"
+
+lemma list_ranI: "\<lbrakk> i < List.length xs; xs ! i = Some b \<rbrakk> \<Longrightarrow> b \<in> list_ran xs"
+unfolding list_ran_def by (drule sym, simp)
+
+lemma list_ran_update_Some:
+  "cl \<in> list_ran (xs[i := (Some b)]) \<Longrightarrow> cl \<in> list_ran xs \<or> cl = b"
+proof -
+  assume assms: "cl \<in> list_ran (xs[i := (Some b)])"
+  have "set (xs[i := Some b]) \<subseteq> insert (Some b) (set xs)"
+    by (simp only: set_update_subset_insert)
+  with assms have "Some cl \<in> insert (Some b) (set xs)"
+    unfolding list_ran_def by fastsimp
+  thus ?thesis
+    unfolding list_ran_def by auto
+qed
+
+lemma list_ran_update_None:
+  "cl \<in> list_ran (xs[i := None]) \<Longrightarrow> cl \<in> list_ran xs"
+proof -
+  assume assms: "cl \<in> list_ran (xs[i := None])"
+  have "set (xs[i := None]) \<subseteq> insert None (set xs)"
+    by (simp only: set_update_subset_insert)
+  with assms show ?thesis
+    unfolding list_ran_def by auto
+qed
+
+definition correctList :: "Clause list \<Rightarrow> Clause option list \<Rightarrow> bool"
+where
+  "correctList rootcls xs =
+  (\<forall>cl \<in> list_ran xs. correctClause rootcls cl \<and> sorted cl \<and> distinct cl)"
+
+subsection {* Checker functions *}
+
+fun lres_thm :: "Clause option list \<Rightarrow> (Lit * ClauseId) \<Rightarrow> Clause \<Rightarrow> Clause Heap" 
+where
+  "lres_thm xs (l, j) cli = (if (j < List.length xs) then (case (xs ! j) of
+  None \<Rightarrow> raise (''MiniSatChecked.res_thm: No resolvant clause in thms array for Conflict step.'')
+  | Some clj \<Rightarrow> res_thm' l cli clj
+ ) else raise ''Error'')"
+
+
+fun ldoProofStep :: " ProofStep \<Rightarrow> (Clause option list  * Clause list) \<Rightarrow> (Clause option list * Clause list) Heap"
+where
+  "ldoProofStep (Conflict saveTo (i, rs)) (xs, rcl) =
+     (case (xs ! i) of
+       None \<Rightarrow> raise (''MiniSatChecked.doProofStep: No starting clause in thms array for Conflict step.'')
+     | Some cli \<Rightarrow> (do
+                      result \<leftarrow> foldM (lres_thm xs) rs cli ;
+                      return ((xs[saveTo:=Some result]), rcl)
+                    done))"
+| "ldoProofStep (Delete cid) (xs, rcl) = return (xs[cid:=None], rcl)"
+| "ldoProofStep (Root cid clause) (xs, rcl) = return (xs[cid:=Some (sort clause)], (remdups(sort clause)) # rcl)"
+| "ldoProofStep (Xstep cid1 cid2) (xs, rcl) = raise ''MiniSatChecked.doProofStep: Xstep constructor found.''"
+| "ldoProofStep (ProofDone b) (xs, rcl) = raise ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
+
+definition lchecker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
+where
+  "lchecker n p i =
+  (do 
+     rcs \<leftarrow> foldM (ldoProofStep) p ([], []);
+     (if (fst rcs ! i) = Some [] then return (snd rcs) 
+                else raise(''No empty clause''))
+   done)"
+
+
+section {* Functional version with RedBlackTrees *}
+
+fun tres_thm :: "(ClauseId, Clause) rbt \<Rightarrow> Lit \<times> ClauseId \<Rightarrow> Clause \<Rightarrow> Clause Heap"
+where
+  "tres_thm t (l, j) cli =
+  (case (RBT.lookup t j) of 
+     None \<Rightarrow> raise (''MiniSatChecked.res_thm: No resolvant clause in thms array for Conflict step.'')
+   | Some clj \<Rightarrow> res_thm' l cli clj)"
+
+fun tdoProofStep :: " ProofStep \<Rightarrow> ((ClauseId, Clause) rbt * Clause list) \<Rightarrow> ((ClauseId, Clause) rbt * Clause list) Heap"
+where
+  "tdoProofStep (Conflict saveTo (i, rs)) (t, rcl) =
+     (case (RBT.lookup t i) of
+       None \<Rightarrow> raise (''MiniSatChecked.doProofStep: No starting clause in thms array for Conflict step.'')
+     | Some cli \<Rightarrow> (do
+                      result \<leftarrow> foldM (tres_thm t) rs cli;
+                      return ((RBT.insert saveTo result t), rcl)
+                    done))"
+| "tdoProofStep (Delete cid) (t, rcl) = return ((RBT.delete cid t), rcl)"
+| "tdoProofStep (Root cid clause) (t, rcl) = return (RBT.insert cid (sort clause) t, (remdups(sort clause)) # rcl)"
+| "tdoProofStep (Xstep cid1 cid2) (t, rcl) = raise ''MiniSatChecked.doProofStep: Xstep constructor found.''"
+| "tdoProofStep (ProofDone b) (t, rcl) = raise ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
+
+definition tchecker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
+where
+  "tchecker n p i =
+  (do 
+     rcs \<leftarrow> foldM (tdoProofStep) p (RBT.Empty, []);
+     (if (RBT.lookup (fst rcs) i) = Some [] then return (snd rcs) 
+                else raise(''No empty clause''))
+   done)"
+
+section {* Code generation setup *}
+
+code_type ProofStep
+  (SML "MinisatProofStep.ProofStep")
+
+code_const ProofDone  and  Root              and  Conflict              and  Delete  and  Xstep
+     (SML "MinisatProofStep.ProofDone" and "MinisatProofStep.Root ((_),/ (_))" and "MinisatProofStep.Conflict ((_),/ (_))" and "MinisatProofStep.Delete" and "MinisatProofStep.Xstep ((_),/ (_))")
+
+export_code checker in SML module_name SAT file -
+export_code tchecker in SML module_name SAT file -
+export_code lchecker in SML module_name SAT file -
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Imperative_HOL/ex/Sorted_List.thy	Thu Apr 08 08:17:27 2010 +0200
@@ -0,0 +1,101 @@
+(*  Title:      HOL/Imperative_HOL/ex/Sorted_List.thy
+    Author:     Lukas Bulwahn, TU Muenchen
+*)
+
+header {* Sorted lists as representation of finite sets *}
+
+theory Sorted_List
+imports Main
+begin
+
+text {* Merge function for two distinct sorted lists to get compound distinct sorted list *}
+   
+fun merge :: "('a::linorder) list \<Rightarrow> 'a list \<Rightarrow> 'a list"
+where
+  "merge (x#xs) (y#ys) =
+  (if x < y then x # merge xs (y#ys) else (if x > y then y # merge (x#xs) ys else x # merge xs ys))"
+| "merge xs [] = xs"
+| "merge [] ys = ys"
+
+text {* The function package does not derive automatically the more general rewrite rule as follows: *}
+lemma merge_Nil[simp]: "merge [] ys = ys"
+by (cases ys) auto
+
+lemma set_merge[simp]: "set (merge xs ys) = set xs \<union> set ys"
+by (induct xs ys rule: merge.induct, auto)
+
+lemma sorted_merge[simp]:
+     "List.sorted (merge xs ys) = (List.sorted xs \<and> List.sorted ys)"
+by (induct xs ys rule: merge.induct, auto simp add: sorted_Cons)
+
+lemma distinct_merge[simp]: "\<lbrakk> distinct xs; distinct ys; List.sorted xs; List.sorted ys \<rbrakk> \<Longrightarrow> distinct (merge xs ys)"
+by (induct xs ys rule: merge.induct, auto simp add: sorted_Cons)
+
+text {* The remove function removes an element from a sorted list *}
+
+fun remove :: "('a :: linorder) \<Rightarrow> 'a list \<Rightarrow> 'a list"
+where
+  "remove a [] = []"
+  |  "remove a (x#xs) = (if a > x then (x # remove a xs) else (if a = x then xs else x#xs))" 
+
+lemma remove': "sorted xs \<and> distinct xs \<Longrightarrow> sorted (remove a xs) \<and> distinct (remove a xs) \<and> set (remove a xs) = set xs - {a}"
+apply (induct xs)
+apply (auto simp add: sorted_Cons)
+done
+
+lemma set_remove[simp]: "\<lbrakk> sorted xs; distinct xs \<rbrakk> \<Longrightarrow> set (remove a xs) = set xs - {a}"
+using remove' by auto
+
+lemma sorted_remove[simp]: "\<lbrakk> sorted xs; distinct xs \<rbrakk> \<Longrightarrow> sorted (remove a xs)" 
+using remove' by auto
+
+lemma distinct_remove[simp]: "\<lbrakk> sorted xs; distinct xs \<rbrakk> \<Longrightarrow> distinct (remove a xs)" 
+using remove' by auto
+
+lemma remove_insort_cancel: "remove a (insort a xs) = xs"
+apply (induct xs)
+apply simp
+apply auto
+done
+
+lemma remove_insort_commute: "\<lbrakk> a \<noteq> b; sorted xs \<rbrakk> \<Longrightarrow> remove b (insort a xs) = insort a (remove b xs)"
+apply (induct xs)
+apply auto
+apply (auto simp add: sorted_Cons)
+apply (case_tac xs)
+apply auto
+done
+
+lemma notinset_remove: "x \<notin> set xs \<Longrightarrow> remove x xs = xs"
+apply (induct xs)
+apply auto
+done
+
+lemma remove1_eq_remove:
+  "sorted xs \<Longrightarrow> distinct xs \<Longrightarrow> remove1 x xs = remove x xs"
+apply (induct xs)
+apply (auto simp add: sorted_Cons)
+apply (subgoal_tac "x \<notin> set xs")
+apply (simp add: notinset_remove)
+apply fastsimp
+done
+
+lemma sorted_remove1:
+  "sorted xs \<Longrightarrow> sorted (remove1 x xs)"
+apply (induct xs)
+apply (auto simp add: sorted_Cons)
+done
+
+subsection {* Efficient member function for sorted lists: smem *}
+
+fun smember :: "('a::linorder) \<Rightarrow> 'a list \<Rightarrow> bool" (infixl "smem" 55)
+where
+  "x smem [] = False"
+|  "x smem (y#ys) = (if x = y then True else (if (x > y) then x smem ys else False))" 
+
+lemma "sorted xs \<Longrightarrow> x smem xs = (x \<in> set xs)" 
+apply (induct xs)
+apply (auto simp add: sorted_Cons)
+done
+
+end
\ No newline at end of file
--- a/src/HOL/Imperative_HOL/ex/Subarray.thy	Wed Apr 07 22:22:49 2010 +0200
+++ b/src/HOL/Imperative_HOL/ex/Subarray.thy	Thu Apr 08 08:17:27 2010 +0200
@@ -1,3 +1,9 @@
+(*  Title:      HOL/Imperative_HOL/ex/Subarray.thy
+    Author:     Lukas Bulwahn, TU Muenchen
+*)
+
+header {* Theorems about sub arrays *}
+
 theory Subarray
 imports Array Sublist
 begin
--- a/src/HOL/Imperative_HOL/ex/Sublist.thy	Wed Apr 07 22:22:49 2010 +0200
+++ b/src/HOL/Imperative_HOL/ex/Sublist.thy	Thu Apr 08 08:17:27 2010 +0200
@@ -1,3 +1,6 @@
+(*  Title:      HOL/Imperative_HOL/ex/Sublist.thy
+    Author:     Lukas Bulwahn, TU Muenchen
+*)
 
 header {* Slices of lists *}
 
--- a/src/HOL/IsaMakefile	Wed Apr 07 22:22:49 2010 +0200
+++ b/src/HOL/IsaMakefile	Thu Apr 08 08:17:27 2010 +0200
@@ -789,6 +789,10 @@
   Imperative_HOL/Ref.thy Imperative_HOL/Imperative_HOL.thy \
   Imperative_HOL/Imperative_HOL_ex.thy \
   Imperative_HOL/ex/Imperative_Quicksort.thy \
+  Imperative_HOL/ex/Imperative_Reverse.thy \
+  Imperative_HOL/ex/Linked_Lists.thy \
+  Imperative_HOL/ex/SatChecker.thy \
+  Imperative_HOL/ex/Sorted_List.thy \
   Imperative_HOL/ex/Subarray.thy \
   Imperative_HOL/ex/Sublist.thy
 	@$(ISABELLE_TOOL) usedir $(OUT)/HOL Imperative_HOL