src/HOL/Tools/cnf_funcs.ML
changeset 20440 e6fe74eebda3
parent 19236 150e8b0fb991
child 20547 796ae7fa1049
equal deleted inserted replaced
20439:1bf42b262a38 20440:e6fe74eebda3
    21 
    21 
    22   For the purpose of SAT proof reconstruction, we also make use of another
    22   For the purpose of SAT proof reconstruction, we also make use of another
    23   representation of clauses, which we call the "raw clauses".
    23   representation of clauses, which we call the "raw clauses".
    24   Raw clauses are of the form
    24   Raw clauses are of the form
    25 
    25 
    26       x1', x2', ..., xn', ~ (x1 | x2 | ... | xn) ==> False |- False ,
    26       [..., x1', x2', ..., xn'] |- False ,
    27 
    27 
    28   where each xi is a literal, and each xi' is the negation normal form of ~xi.
    28   where each xi is a literal, and each xi' is the negation normal form of ~xi.
    29 
    29 
    30   Raw clauses may contain further hyps of the form "~ clause ==> False".
       
    31   Literals are successively removed from the hyps of raw clauses by resolution
    30   Literals are successively removed from the hyps of raw clauses by resolution
    32   during SAT proof reconstruction.
    31   during SAT proof reconstruction.
    33 *)
    32 *)
    34 
    33 
    35 signature CNF =
    34 signature CNF =
    37 	val is_atom           : Term.term -> bool
    36 	val is_atom           : Term.term -> bool
    38 	val is_literal        : Term.term -> bool
    37 	val is_literal        : Term.term -> bool
    39 	val is_clause         : Term.term -> bool
    38 	val is_clause         : Term.term -> bool
    40 	val clause_is_trivial : Term.term -> bool
    39 	val clause_is_trivial : Term.term -> bool
    41 
    40 
    42 	val clause2raw_thm         : Thm.thm -> Thm.thm
    41 	val clause2raw_thm : Thm.thm -> Thm.thm
    43 	val rawhyps2clausehyps_thm : Thm.thm -> Thm.thm
       
    44 
    42 
    45 	val weakening_tac : int -> Tactical.tactic  (* removes the first hypothesis of a subgoal *)
    43 	val weakening_tac : int -> Tactical.tactic  (* removes the first hypothesis of a subgoal *)
    46 
    44 
    47 	val make_cnf_thm  : Theory.theory -> Term.term -> Thm.thm
    45 	val make_cnf_thm  : Theory.theory -> Term.term -> Thm.thm
    48 	val make_cnfx_thm : Theory.theory -> Term.term ->  Thm.thm
    46 	val make_cnfx_thm : Theory.theory -> Term.term ->  Thm.thm
    51 end;
    49 end;
    52 
    50 
    53 structure cnf : CNF =
    51 structure cnf : CNF =
    54 struct
    52 struct
    55 
    53 
    56 (* string -> Thm.thm *)
    54 fun thm_by_auto (G : string) : thm =
    57 fun thm_by_auto G =
       
    58 	prove_goal (the_context ()) G (fn prems => [cut_facts_tac prems 1, Auto_tac]);
    55 	prove_goal (the_context ()) G (fn prems => [cut_facts_tac prems 1, Auto_tac]);
    59 
    56 
    60 (* Thm.thm *)
    57 (* Thm.thm *)
    61 val clause2raw_notE      = thm_by_auto "[| P; ~P |] ==> False";
    58 val clause2raw_notE      = thm_by_auto "[| P; ~P |] ==> False";
    62 val clause2raw_not_disj  = thm_by_auto "[| ~P; ~Q |] ==> ~(P | Q)";
    59 val clause2raw_not_disj  = thm_by_auto "[| ~P; ~Q |] ==> ~(P | Q)";
   138 		has_duals (collect_literals c [])
   135 		has_duals (collect_literals c [])
   139 	end;
   136 	end;
   140 
   137 
   141 (* ------------------------------------------------------------------------- *)
   138 (* ------------------------------------------------------------------------- *)
   142 (* clause2raw_thm: translates a clause into a raw clause, i.e.               *)
   139 (* clause2raw_thm: translates a clause into a raw clause, i.e.               *)
   143 (*        ... |- x1 | ... | xn                                               *)
   140 (*        [...] |- x1 | ... | xn                                             *)
   144 (*      (where each xi is a literal) is translated to                        *)
   141 (*      (where each xi is a literal) is translated to                        *)
   145 (*        ~(x1 | ... | xn) ==> False, x1', ..., xn' |- False ,               *)
   142 (*        [..., x1', ..., xn'] |- False ,                                    *)
   146 (*      where each xi' is the negation normal form of ~xi.                   *)
   143 (*      where each xi' is the negation normal form of ~xi                    *)
   147 (* ------------------------------------------------------------------------- *)
   144 (* ------------------------------------------------------------------------- *)
   148 
   145 
   149 (* Thm.thm -> Thm.thm *)
   146 (* Thm.thm -> Thm.thm *)
   150 
   147 
   151 fun clause2raw_thm c =
   148 fun clause2raw_thm clause =
   152 let
   149 let
   153 	val disj               = HOLogic.dest_Trueprop (prop_of c)
       
   154 	val not_disj_imp_false = Logic.mk_implies (HOLogic.mk_Trueprop (HOLogic.mk_not disj), HOLogic.mk_Trueprop HOLogic.false_const)
       
   155 	val thm1 = Thm.assume (cterm_of (theory_of_thm c) not_disj_imp_false)  (* ~(x1 | ... | xn) ==> False |- ~(x1 | ... | xn) ==> False *)
       
   156 	(* eliminates negated disjunctions from the i-th premise, possibly *)
   150 	(* eliminates negated disjunctions from the i-th premise, possibly *)
   157 	(* adding new premises, then continues with the (i+1)-th premise   *)
   151 	(* adding new premises, then continues with the (i+1)-th premise   *)
   158 	(* Thm.thm -> int -> Thm.thm *)
   152 	(* int -> Thm.thm -> Thm.thm *)
   159 	fun not_disj_to_prem thm i =
   153 	fun not_disj_to_prem i thm =
   160 		if i > nprems_of thm then
   154 		if i > nprems_of thm then
   161 			thm
   155 			thm
   162 		else
   156 		else
   163 			not_disj_to_prem (Seq.hd (REPEAT_DETERM (rtac clause2raw_not_disj i) thm)) (i+1)
   157 			not_disj_to_prem (i+1) (Seq.hd (REPEAT_DETERM (rtac clause2raw_not_disj i) thm))
   164 	val thm2 = not_disj_to_prem thm1 1  (* ~(x1 | ... | xn) ==> False |- ~x1 ==> ... ==> ~xn ==> False *)
   158 	(* moves all premises to hyps, i.e. "[...] |- A1 ==> ... ==> An ==> B" *)
   165 	val thm3 = Seq.hd (TRYALL (rtac clause2raw_not_not) thm2)  (* ~(x1 | ... | xn) ==> False |- x1' ==> ... ==> xn' ==> False *)
   159 	(* becomes "[..., A1, ..., An] |- B"                                   *)
   166 	val thy3 = theory_of_thm thm3
   160 	(* Thm.thm -> Thm.thm *)
   167 	val thm4 = fold (fn prem => fn thm => Thm.implies_elim thm (Thm.assume (cterm_of thy3 prem))) (prems_of thm3) thm3  (* ~(x1 | ... | xn) ==> False, x1', ..., xn' |- False *)
   161 	fun prems_to_hyps thm =
       
   162 		fold (fn cprem => fn thm' =>
       
   163 			Thm.implies_elim thm' (Thm.assume cprem)) (cprems_of thm) thm
   168 in
   164 in
   169 	thm4
   165 	(* [...] |- ~(x1 | ... | xn) ==> False *)
       
   166 	(clause2raw_notE OF [clause])
       
   167 	(* [...] |- ~x1 ==> ... ==> ~xn ==> False *)
       
   168 	|> not_disj_to_prem 1
       
   169 	(* [...] |- x1' ==> ... ==> xn' ==> False *)
       
   170 	|> Seq.hd o TRYALL (rtac clause2raw_not_not)
       
   171 	(* [..., x1', ..., xn'] |- False *)
       
   172 	|> prems_to_hyps
   170 end;
   173 end;
   171 
       
   172 (* ------------------------------------------------------------------------- *)
       
   173 (* rawhyps2clausehyps_thm: translates all hyps of the form "~P ==> False" to *)
       
   174 (*      hyps of the form "P"                                                 *)
       
   175 (* ------------------------------------------------------------------------- *)
       
   176 
       
   177 (* Thm.thm -> Thm.thm *)
       
   178 
       
   179 fun rawhyps2clausehyps_thm c =
       
   180 	fold (fn hyp => fn thm =>
       
   181 		case hyp of Const ("==>", _) $ (Const ("Trueprop", _) $ (Const ("Not", _) $ P)) $ (Const ("Trueprop", _) $ Const ("False", _)) =>
       
   182 			let
       
   183 				val cterm = cterm_of (theory_of_thm thm)
       
   184 				val thm1  = Thm.implies_intr (cterm hyp) thm  (* hyps |- (~P ==> False) ==> goal *)
       
   185 				val varP  = Var (("P", 0), HOLogic.boolT)
       
   186 				val notE  = Thm.instantiate ([], [(cterm varP, cterm P)]) clause2raw_notE  (* P ==> ~P ==> False *)
       
   187 				val notE' = Thm.implies_elim notE (Thm.assume (cterm (HOLogic.mk_Trueprop P)))  (* P |- ~P ==> False *)
       
   188 				val thm2  = Thm.implies_elim thm1 notE'  (* hyps, P |- goal *)
       
   189 			in
       
   190 				thm2
       
   191 			end
       
   192 		          | _                                                                                                                  =>
       
   193 			thm) (#hyps (rep_thm c)) c;
       
   194 
   174 
   195 (* ------------------------------------------------------------------------- *)
   175 (* ------------------------------------------------------------------------- *)
   196 (* inst_thm: instantiates a theorem with a list of terms                     *)
   176 (* inst_thm: instantiates a theorem with a list of terms                     *)
   197 (* ------------------------------------------------------------------------- *)
   177 (* ------------------------------------------------------------------------- *)
   198 
   178