src/HOL/Imperative_HOL/ex/SatChecker.thy
changeset 68028 1f9f973eed2a
parent 66453 cc19f7ca2ed6
child 69085 9999d7823b8f
equal deleted inserted replaced
68027:64559e1ca05b 68028:1f9f973eed2a
   171 
   171 
   172 subsection\<open>Function definitions\<close>
   172 subsection\<open>Function definitions\<close>
   173 
   173 
   174 primrec res_mem :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   174 primrec res_mem :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   175 where
   175 where
   176   "res_mem l [] = raise ''MiniSatChecked.res_thm: Cannot find literal''"
   176   "res_mem l [] = raise STR ''MiniSatChecked.res_thm: Cannot find literal''"
   177 | "res_mem l (x#xs) = (if (x = l) then return xs else do { v \<leftarrow> res_mem l xs; return (x # v) })"
   177 | "res_mem l (x#xs) = (if (x = l) then return xs else do { v \<leftarrow> res_mem l xs; return (x # v) })"
   178 
   178 
   179 fun resolve1 :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   179 fun resolve1 :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   180 where
   180 where
   181   "resolve1 l (x#xs) (y#ys) =
   181   "resolve1 l (x#xs) (y#ys) =
   182   (if (x = l) then return (merge xs (y#ys))
   182   (if (x = l) then return (merge xs (y#ys))
   183   else (if (x < y) then do { v \<leftarrow> resolve1 l xs (y#ys); return (x # v) }
   183   else (if (x < y) then do { v \<leftarrow> resolve1 l xs (y#ys); return (x # v) }
   184   else (if (x > y) then do { v \<leftarrow> resolve1 l (x#xs) ys; return (y # v) }
   184   else (if (x > y) then do { v \<leftarrow> resolve1 l (x#xs) ys; return (y # v) }
   185   else do { v \<leftarrow> resolve1 l xs ys; return (x # v) })))"
   185   else do { v \<leftarrow> resolve1 l xs ys; return (x # v) })))"
   186 | "resolve1 l [] ys = raise ''MiniSatChecked.res_thm: Cannot find literal''"
   186 | "resolve1 l [] ys = raise STR ''MiniSatChecked.res_thm: Cannot find literal''"
   187 | "resolve1 l xs [] = res_mem l xs"
   187 | "resolve1 l xs [] = res_mem l xs"
   188 
   188 
   189 fun resolve2 :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap" 
   189 fun resolve2 :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap" 
   190 where
   190 where
   191   "resolve2 l (x#xs) (y#ys) =
   191   "resolve2 l (x#xs) (y#ys) =
   192   (if (y = l) then return (merge (x#xs) ys)
   192   (if (y = l) then return (merge (x#xs) ys)
   193   else (if (x < y) then do { v \<leftarrow> resolve2 l xs (y#ys); return (x # v) }
   193   else (if (x < y) then do { v \<leftarrow> resolve2 l xs (y#ys); return (x # v) }
   194   else (if (x > y) then do { v \<leftarrow> resolve2 l (x#xs) ys; return (y # v) }
   194   else (if (x > y) then do { v \<leftarrow> resolve2 l (x#xs) ys; return (y # v) }
   195   else do { v \<leftarrow> resolve2 l xs ys; return (x # v) })))"
   195   else do { v \<leftarrow> resolve2 l xs ys; return (x # v) })))"
   196   | "resolve2 l xs [] = raise ''MiniSatChecked.res_thm: Cannot find literal''"
   196   | "resolve2 l xs [] = raise STR ''MiniSatChecked.res_thm: Cannot find literal''"
   197   | "resolve2 l [] ys = res_mem l ys"
   197   | "resolve2 l [] ys = res_mem l ys"
   198 
   198 
   199 fun res_thm' :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   199 fun res_thm' :: "Lit \<Rightarrow> Clause \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   200 where
   200 where
   201   "res_thm' l (x#xs) (y#ys) = 
   201   "res_thm' l (x#xs) (y#ys) = 
   202   (if (x = l \<or> x = compl l) then resolve2 (compl x) xs (y#ys)
   202   (if (x = l \<or> x = compl l) then resolve2 (compl x) xs (y#ys)
   203   else (if (y = l \<or> y = compl l) then resolve1 (compl y) (x#xs) ys
   203   else (if (y = l \<or> y = compl l) then resolve1 (compl y) (x#xs) ys
   204   else (if (x < y) then (res_thm' l xs (y#ys)) \<bind> (\<lambda>v. return (x # v))
   204   else (if (x < y) then (res_thm' l xs (y#ys)) \<bind> (\<lambda>v. return (x # v))
   205   else (if (x > y) then (res_thm' l (x#xs) ys) \<bind> (\<lambda>v. return (y # v))
   205   else (if (x > y) then (res_thm' l (x#xs) ys) \<bind> (\<lambda>v. return (y # v))
   206   else (res_thm' l xs ys) \<bind> (\<lambda>v. return (x # v))))))"
   206   else (res_thm' l xs ys) \<bind> (\<lambda>v. return (x # v))))))"
   207 | "res_thm' l [] ys = raise (''MiniSatChecked.res_thm: Cannot find literal'')"
   207 | "res_thm' l [] ys = raise STR ''MiniSatChecked.res_thm: Cannot find literal''"
   208 | "res_thm' l xs [] = raise (''MiniSatChecked.res_thm: Cannot find literal'')"
   208 | "res_thm' l xs [] = raise STR ''MiniSatChecked.res_thm: Cannot find literal''"
   209 
   209 
   210 declare res_mem.simps [simp del] resolve1.simps [simp del] resolve2.simps [simp del] res_thm'.simps [simp del]
   210 declare res_mem.simps [simp del] resolve1.simps [simp del] resolve2.simps [simp del] res_thm'.simps [simp del]
   211 
   211 
   212 subsection \<open>Proofs about these functions\<close>
   212 subsection \<open>Proofs about these functions\<close>
   213 
   213 
   412 
   412 
   413 definition get_clause :: "Clause option array \<Rightarrow> ClauseId \<Rightarrow> Clause Heap"
   413 definition get_clause :: "Clause option array \<Rightarrow> ClauseId \<Rightarrow> Clause Heap"
   414 where
   414 where
   415   "get_clause a i = 
   415   "get_clause a i = 
   416        do { c \<leftarrow> Array.nth a i;
   416        do { c \<leftarrow> Array.nth a i;
   417            (case c of None \<Rightarrow> raise (''Clause not found'')
   417            (case c of None \<Rightarrow> raise STR ''Clause not found''
   418                     | Some x \<Rightarrow> return x)
   418                     | Some x \<Rightarrow> return x)
   419        }"
   419        }"
   420 
   420 
   421 
   421 
   422 primrec res_thm2 :: "Clause option array \<Rightarrow> (Lit * ClauseId) \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   422 primrec res_thm2 :: "Clause option array \<Rightarrow> (Lit * ClauseId) \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   423 where
   423 where
   424   "res_thm2 a (l, j) cli =
   424   "res_thm2 a (l, j) cli =
   425   ( if l = 0 then raise(''Illegal literal'')
   425   ( if l = 0 then raise STR ''Illegal literal''
   426     else
   426     else
   427      do { clj \<leftarrow> get_clause a j;
   427      do { clj \<leftarrow> get_clause a j;
   428          res_thm' l cli clj
   428          res_thm' l cli clj
   429      })"
   429      })"
   430 
   430 
   443      Array.upd saveTo (Some result) a; 
   443      Array.upd saveTo (Some result) a; 
   444      return rcs
   444      return rcs
   445   }"
   445   }"
   446 | "doProofStep2 a (Delete cid) rcs = do { Array.upd cid None a; return rcs }"
   446 | "doProofStep2 a (Delete cid) rcs = do { Array.upd cid None a; return rcs }"
   447 | "doProofStep2 a (Root cid clause) rcs = do { Array.upd cid (Some (remdups (sort clause))) a; return (clause # rcs) }"
   447 | "doProofStep2 a (Root cid clause) rcs = do { Array.upd cid (Some (remdups (sort clause))) a; return (clause # rcs) }"
   448 | "doProofStep2 a (Xstep cid1 cid2) rcs = raise ''MiniSatChecked.doProofStep: Xstep constructor found.''"
   448 | "doProofStep2 a (Xstep cid1 cid2) rcs = raise STR ''MiniSatChecked.doProofStep: Xstep constructor found.''"
   449 | "doProofStep2 a (ProofDone b) rcs = raise ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
   449 | "doProofStep2 a (ProofDone b) rcs = raise STR ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
   450 
   450 
   451 definition checker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
   451 definition checker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
   452 where
   452 where
   453   "checker n p i =
   453   "checker n p i =
   454   do {
   454   do {
   455      a \<leftarrow> Array.new n None;
   455      a \<leftarrow> Array.new n None;
   456      rcs \<leftarrow> foldM (doProofStep2 a) p [];
   456      rcs \<leftarrow> foldM (doProofStep2 a) p [];
   457      ec \<leftarrow> Array.nth a i;
   457      ec \<leftarrow> Array.nth a i;
   458      (if ec = Some [] then return rcs 
   458      (if ec = Some [] then return rcs 
   459                 else raise(''No empty clause''))
   459                 else raise STR ''No empty clause'')
   460   }"
   460   }"
   461 
   461 
   462 lemma effect_case_option:
   462 lemma effect_case_option:
   463   assumes "effect (case x of None \<Rightarrow> n | Some y \<Rightarrow> s y) h h' r"
   463   assumes "effect (case x of None \<Rightarrow> n | Some y \<Rightarrow> s y) h h' r"
   464   obtains "x = None" "effect n h h' r"
   464   obtains "x = None" "effect n h h' r"
   639 subsection \<open>Checker functions\<close>
   639 subsection \<open>Checker functions\<close>
   640 
   640 
   641 primrec lres_thm :: "Clause option list \<Rightarrow> (Lit * ClauseId) \<Rightarrow> Clause \<Rightarrow> Clause Heap" 
   641 primrec lres_thm :: "Clause option list \<Rightarrow> (Lit * ClauseId) \<Rightarrow> Clause \<Rightarrow> Clause Heap" 
   642 where
   642 where
   643   "lres_thm xs (l, j) cli = (if (j < List.length xs) then (case (xs ! j) of
   643   "lres_thm xs (l, j) cli = (if (j < List.length xs) then (case (xs ! j) of
   644   None \<Rightarrow> raise (''MiniSatChecked.res_thm: No resolvant clause in thms array for Conflict step.'')
   644   None \<Rightarrow> raise STR ''MiniSatChecked.res_thm: No resolvant clause in thms array for Conflict step.''
   645   | Some clj \<Rightarrow> res_thm' l cli clj
   645   | Some clj \<Rightarrow> res_thm' l cli clj
   646  ) else raise ''Error'')"
   646  ) else raise STR ''Error'')"
   647 
   647 
   648 
   648 
   649 fun ldoProofStep :: " ProofStep \<Rightarrow> (Clause option list  * Clause list) \<Rightarrow> (Clause option list * Clause list) Heap"
   649 fun ldoProofStep :: " ProofStep \<Rightarrow> (Clause option list  * Clause list) \<Rightarrow> (Clause option list * Clause list) Heap"
   650 where
   650 where
   651   "ldoProofStep (Conflict saveTo (i, rs)) (xs, rcl) =
   651   "ldoProofStep (Conflict saveTo (i, rs)) (xs, rcl) =
   652      (case (xs ! i) of
   652      (case (xs ! i) of
   653        None \<Rightarrow> raise (''MiniSatChecked.doProofStep: No starting clause in thms array for Conflict step.'')
   653        None \<Rightarrow> raise STR ''MiniSatChecked.doProofStep: No starting clause in thms array for Conflict step.''
   654      | Some cli \<Rightarrow> do {
   654      | Some cli \<Rightarrow> do {
   655                       result \<leftarrow> foldM (lres_thm xs) rs cli ;
   655                       result \<leftarrow> foldM (lres_thm xs) rs cli ;
   656                       return ((xs[saveTo:=Some result]), rcl)
   656                       return ((xs[saveTo:=Some result]), rcl)
   657                    })"
   657                    })"
   658 | "ldoProofStep (Delete cid) (xs, rcl) = return (xs[cid:=None], rcl)"
   658 | "ldoProofStep (Delete cid) (xs, rcl) = return (xs[cid:=None], rcl)"
   659 | "ldoProofStep (Root cid clause) (xs, rcl) = return (xs[cid:=Some (sort clause)], (remdups(sort clause)) # rcl)"
   659 | "ldoProofStep (Root cid clause) (xs, rcl) = return (xs[cid:=Some (sort clause)], (remdups(sort clause)) # rcl)"
   660 | "ldoProofStep (Xstep cid1 cid2) (xs, rcl) = raise ''MiniSatChecked.doProofStep: Xstep constructor found.''"
   660 | "ldoProofStep (Xstep cid1 cid2) (xs, rcl) = raise STR ''MiniSatChecked.doProofStep: Xstep constructor found.''"
   661 | "ldoProofStep (ProofDone b) (xs, rcl) = raise ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
   661 | "ldoProofStep (ProofDone b) (xs, rcl) = raise STR ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
   662 
   662 
   663 definition lchecker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
   663 definition lchecker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
   664 where
   664 where
   665   "lchecker n p i =
   665   "lchecker n p i =
   666   do {
   666   do {
   667      rcs \<leftarrow> foldM (ldoProofStep) p ([], []);
   667      rcs \<leftarrow> foldM (ldoProofStep) p ([], []);
   668      (if (fst rcs ! i) = Some [] then return (snd rcs) 
   668      (if (fst rcs ! i) = Some [] then return (snd rcs) 
   669                 else raise(''No empty clause''))
   669                 else raise STR ''No empty clause'')
   670   }"
   670   }"
   671 
   671 
   672 
   672 
   673 section \<open>Functional version with RedBlackTrees\<close>
   673 section \<open>Functional version with RedBlackTrees\<close>
   674 
   674 
   675 primrec tres_thm :: "(ClauseId, Clause) RBT_Impl.rbt \<Rightarrow> Lit \<times> ClauseId \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   675 primrec tres_thm :: "(ClauseId, Clause) RBT_Impl.rbt \<Rightarrow> Lit \<times> ClauseId \<Rightarrow> Clause \<Rightarrow> Clause Heap"
   676 where
   676 where
   677   "tres_thm t (l, j) cli =
   677   "tres_thm t (l, j) cli =
   678   (case (rbt_lookup t j) of 
   678   (case (rbt_lookup t j) of 
   679      None \<Rightarrow> raise (''MiniSatChecked.res_thm: No resolvant clause in thms array for Conflict step.'')
   679      None \<Rightarrow> raise STR ''MiniSatChecked.res_thm: No resolvant clause in thms array for Conflict step.''
   680    | Some clj \<Rightarrow> res_thm' l cli clj)"
   680    | Some clj \<Rightarrow> res_thm' l cli clj)"
   681 
   681 
   682 fun tdoProofStep :: " ProofStep \<Rightarrow> ((ClauseId, Clause) RBT_Impl.rbt * Clause list) \<Rightarrow> ((ClauseId, Clause) RBT_Impl.rbt * Clause list) Heap"
   682 fun tdoProofStep :: " ProofStep \<Rightarrow> ((ClauseId, Clause) RBT_Impl.rbt * Clause list) \<Rightarrow> ((ClauseId, Clause) RBT_Impl.rbt * Clause list) Heap"
   683 where
   683 where
   684   "tdoProofStep (Conflict saveTo (i, rs)) (t, rcl) =
   684   "tdoProofStep (Conflict saveTo (i, rs)) (t, rcl) =
   685      (case (rbt_lookup t i) of
   685      (case (rbt_lookup t i) of
   686        None \<Rightarrow> raise (''MiniSatChecked.doProofStep: No starting clause in thms array for Conflict step.'')
   686        None \<Rightarrow> raise STR ''MiniSatChecked.doProofStep: No starting clause in thms array for Conflict step.''
   687      | Some cli \<Rightarrow> do {
   687      | Some cli \<Rightarrow> do {
   688                       result \<leftarrow> foldM (tres_thm t) rs cli;
   688                       result \<leftarrow> foldM (tres_thm t) rs cli;
   689                       return ((rbt_insert saveTo result t), rcl)
   689                       return ((rbt_insert saveTo result t), rcl)
   690                    })"
   690                    })"
   691 | "tdoProofStep (Delete cid) (t, rcl) = return ((rbt_delete cid t), rcl)"
   691 | "tdoProofStep (Delete cid) (t, rcl) = return ((rbt_delete cid t), rcl)"
   692 | "tdoProofStep (Root cid clause) (t, rcl) = return (rbt_insert cid (sort clause) t, (remdups(sort clause)) # rcl)"
   692 | "tdoProofStep (Root cid clause) (t, rcl) = return (rbt_insert cid (sort clause) t, (remdups(sort clause)) # rcl)"
   693 | "tdoProofStep (Xstep cid1 cid2) (t, rcl) = raise ''MiniSatChecked.doProofStep: Xstep constructor found.''"
   693 | "tdoProofStep (Xstep cid1 cid2) (t, rcl) = raise STR ''MiniSatChecked.doProofStep: Xstep constructor found.''"
   694 | "tdoProofStep (ProofDone b) (t, rcl) = raise ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
   694 | "tdoProofStep (ProofDone b) (t, rcl) = raise STR ''MiniSatChecked.doProofStep: ProofDone constructor found.''"
   695 
   695 
   696 definition tchecker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
   696 definition tchecker :: "nat \<Rightarrow> ProofStep list \<Rightarrow> nat \<Rightarrow> Clause list Heap"
   697 where
   697 where
   698   "tchecker n p i =
   698   "tchecker n p i =
   699   do {
   699   do {
   700      rcs \<leftarrow> foldM (tdoProofStep) p (RBT_Impl.Empty, []);
   700      rcs \<leftarrow> foldM (tdoProofStep) p (RBT_Impl.Empty, []);
   701      (if (rbt_lookup (fst rcs) i) = Some [] then return (snd rcs) 
   701      (if (rbt_lookup (fst rcs) i) = Some [] then return (snd rcs) 
   702                 else raise(''No empty clause''))
   702                 else raise STR ''No empty clause'')
   703   }"
   703   }"
   704 
   704 
   705 export_code checker tchecker lchecker checking SML
   705 export_code checker tchecker lchecker checking SML
   706 
   706 
   707 end
   707 end