src/HOL/Integ/cooper_proof.ML
author chaieb
Mon Aug 30 12:01:52 2004 +0200 (2004-08-30)
changeset 15164 5d7c96e0f9dc
parent 15123 4c49281dc9a8
child 15165 a1e84e86c583
permissions -rw-r--r--
m dvd t where m is non numeral is now catched!
     1 (*  Title:      HOL/Integ/cooper_proof.ML
     2     ID:         $Id$
     3     Author:     Amine Chaieb and Tobias Nipkow, TU Muenchen
     4 
     5 File containing the implementation of the proof
     6 generation for Cooper Algorithm
     7 *)
     8 
     9 
    10 signature COOPER_PROOF =
    11 sig
    12   val qe_Not : thm
    13   val qe_conjI : thm
    14   val qe_disjI : thm
    15   val qe_impI : thm
    16   val qe_eqI : thm
    17   val qe_exI : thm
    18   val list_to_set : typ -> term list -> term
    19   val qe_get_terms : thm -> term * term
    20   val cooper_prv  : Sign.sg -> term -> term -> thm
    21   val proof_of_evalc : Sign.sg -> term -> thm
    22   val proof_of_cnnf : Sign.sg -> term -> (term -> thm) -> thm
    23   val proof_of_linform : Sign.sg -> string list -> term -> thm
    24   val proof_of_adjustcoeffeq : Sign.sg -> term -> int -> term -> thm
    25   val prove_elementar : Sign.sg -> string -> term -> thm
    26   val thm_of : Sign.sg -> (term -> (term list * (thm list -> thm))) -> term -> thm
    27   val timef : (unit->thm) -> thm
    28   val prtime : unit -> unit
    29   val time_reset  : unit -> unit
    30   val timef2 : (unit->thm) -> thm
    31   val prtime2 : unit -> unit
    32   val time_reset2  : unit -> unit
    33 end;
    34 
    35 structure CooperProof : COOPER_PROOF =
    36 struct
    37 open CooperDec;
    38 
    39 (*
    40 val presburger_ss = simpset_of (theory "Presburger")
    41   addsimps [zdiff_def] delsimps [symmetric zdiff_def];
    42 *)
    43 
    44 val presburger_ss = simpset_of (theory "Presburger")
    45   addsimps[diff_int_def] delsimps [thm"diff_int_def_symmetric"];
    46 val cboolT = ctyp_of (sign_of HOL.thy) HOLogic.boolT;
    47 
    48 (*Theorems that will be used later for the proofgeneration*)
    49 
    50 val zdvd_iff_zmod_eq_0 = thm "zdvd_iff_zmod_eq_0";
    51 val unity_coeff_ex = thm "unity_coeff_ex";
    52 
    53 (* Thorems for proving the adjustment of the coeffitients*)
    54 
    55 val ac_lt_eq =  thm "ac_lt_eq";
    56 val ac_eq_eq = thm "ac_eq_eq";
    57 val ac_dvd_eq = thm "ac_dvd_eq";
    58 val ac_pi_eq = thm "ac_pi_eq";
    59 
    60 (* The logical compination of the sythetised properties*)
    61 val qe_Not = thm "qe_Not";
    62 val qe_conjI = thm "qe_conjI";
    63 val qe_disjI = thm "qe_disjI";
    64 val qe_impI = thm "qe_impI";
    65 val qe_eqI = thm "qe_eqI";
    66 val qe_exI = thm "qe_exI";
    67 val qe_ALLI = thm "qe_ALLI";
    68 
    69 (*Modulo D property for Pminusinf an Plusinf *)
    70 val fm_modd_minf = thm "fm_modd_minf";
    71 val not_dvd_modd_minf = thm "not_dvd_modd_minf";
    72 val dvd_modd_minf = thm "dvd_modd_minf";
    73 
    74 val fm_modd_pinf = thm "fm_modd_pinf";
    75 val not_dvd_modd_pinf = thm "not_dvd_modd_pinf";
    76 val dvd_modd_pinf = thm "dvd_modd_pinf";
    77 
    78 (* the minusinfinity proprty*)
    79 
    80 val fm_eq_minf = thm "fm_eq_minf";
    81 val neq_eq_minf = thm "neq_eq_minf";
    82 val eq_eq_minf = thm "eq_eq_minf";
    83 val le_eq_minf = thm "le_eq_minf";
    84 val len_eq_minf = thm "len_eq_minf";
    85 val not_dvd_eq_minf = thm "not_dvd_eq_minf";
    86 val dvd_eq_minf = thm "dvd_eq_minf";
    87 
    88 (* the Plusinfinity proprty*)
    89 
    90 val fm_eq_pinf = thm "fm_eq_pinf";
    91 val neq_eq_pinf = thm "neq_eq_pinf";
    92 val eq_eq_pinf = thm "eq_eq_pinf";
    93 val le_eq_pinf = thm "le_eq_pinf";
    94 val len_eq_pinf = thm "len_eq_pinf";
    95 val not_dvd_eq_pinf = thm "not_dvd_eq_pinf";
    96 val dvd_eq_pinf = thm "dvd_eq_pinf";
    97 
    98 (*Logical construction of the Property*)
    99 val eq_minf_conjI = thm "eq_minf_conjI";
   100 val eq_minf_disjI = thm "eq_minf_disjI";
   101 val modd_minf_disjI = thm "modd_minf_disjI";
   102 val modd_minf_conjI = thm "modd_minf_conjI";
   103 
   104 val eq_pinf_conjI = thm "eq_pinf_conjI";
   105 val eq_pinf_disjI = thm "eq_pinf_disjI";
   106 val modd_pinf_disjI = thm "modd_pinf_disjI";
   107 val modd_pinf_conjI = thm "modd_pinf_conjI";
   108 
   109 (*Cooper Backwards...*)
   110 (*Bset*)
   111 val not_bst_p_fm = thm "not_bst_p_fm";
   112 val not_bst_p_ne = thm "not_bst_p_ne";
   113 val not_bst_p_eq = thm "not_bst_p_eq";
   114 val not_bst_p_gt = thm "not_bst_p_gt";
   115 val not_bst_p_lt = thm "not_bst_p_lt";
   116 val not_bst_p_ndvd = thm "not_bst_p_ndvd";
   117 val not_bst_p_dvd = thm "not_bst_p_dvd";
   118 
   119 (*Aset*)
   120 val not_ast_p_fm = thm "not_ast_p_fm";
   121 val not_ast_p_ne = thm "not_ast_p_ne";
   122 val not_ast_p_eq = thm "not_ast_p_eq";
   123 val not_ast_p_gt = thm "not_ast_p_gt";
   124 val not_ast_p_lt = thm "not_ast_p_lt";
   125 val not_ast_p_ndvd = thm "not_ast_p_ndvd";
   126 val not_ast_p_dvd = thm "not_ast_p_dvd";
   127 
   128 (*Logical construction of the prop*)
   129 (*Bset*)
   130 val not_bst_p_conjI = thm "not_bst_p_conjI";
   131 val not_bst_p_disjI = thm "not_bst_p_disjI";
   132 val not_bst_p_Q_elim = thm "not_bst_p_Q_elim";
   133 
   134 (*Aset*)
   135 val not_ast_p_conjI = thm "not_ast_p_conjI";
   136 val not_ast_p_disjI = thm "not_ast_p_disjI";
   137 val not_ast_p_Q_elim = thm "not_ast_p_Q_elim";
   138 
   139 (*Cooper*)
   140 val cppi_eq = thm "cppi_eq";
   141 val cpmi_eq = thm "cpmi_eq";
   142 
   143 (*Others*)
   144 val simp_from_to = thm "simp_from_to";
   145 val P_eqtrue = thm "P_eqtrue";
   146 val P_eqfalse = thm "P_eqfalse";
   147 
   148 (*For Proving NNF*)
   149 
   150 val nnf_nn = thm "nnf_nn";
   151 val nnf_im = thm "nnf_im";
   152 val nnf_eq = thm "nnf_eq";
   153 val nnf_sdj = thm "nnf_sdj";
   154 val nnf_ncj = thm "nnf_ncj";
   155 val nnf_nim = thm "nnf_nim";
   156 val nnf_neq = thm "nnf_neq";
   157 val nnf_ndj = thm "nnf_ndj";
   158 
   159 (*For Proving term linearizition*)
   160 val linearize_dvd = thm "linearize_dvd";
   161 val lf_lt = thm "lf_lt";
   162 val lf_eq = thm "lf_eq";
   163 val lf_dvd = thm "lf_dvd";
   164 
   165 
   166 (* ------------------------------------------------------------------------- *)
   167 (*This function norm_zero_one  replaces the occurences of Numeral1 and Numeral0*)
   168 (*Respectively by their abstract representation Const("1",..) and COnst("0",..)*)
   169 (*this is necessary because the theorems use this representation.*)
   170 (* This function should be elminated in next versions...*)
   171 (* ------------------------------------------------------------------------- *)
   172 
   173 fun norm_zero_one fm = case fm of
   174   (Const ("op *",_) $ c $ t) => 
   175     if c = one then (norm_zero_one t)
   176     else if (dest_numeral c = ~1) 
   177          then (Const("uminus",HOLogic.intT --> HOLogic.intT) $ (norm_zero_one t))
   178          else (HOLogic.mk_binop "op *" (norm_zero_one c,norm_zero_one t))
   179   |(node $ rest) => ((norm_zero_one node)$(norm_zero_one rest))
   180   |(Abs(x,T,p)) => (Abs(x,T,(norm_zero_one p)))
   181   |_ => fm;
   182 
   183 (* ------------------------------------------------------------------------- *)
   184 (*function list to Set, constructs a set containing all elements of a given list.*)
   185 (* ------------------------------------------------------------------------- *)
   186 fun list_to_set T1 l = let val T = (HOLogic.mk_setT T1) in 
   187 	case l of 
   188 		[] => Const ("{}",T)
   189 		|(h::t) => Const("insert", T1 --> (T --> T)) $ h $(list_to_set T1 t)
   190 		end;
   191 		
   192 (* ------------------------------------------------------------------------- *)
   193 (* Returns both sides of an equvalence in the theorem*)
   194 (* ------------------------------------------------------------------------- *)
   195 fun qe_get_terms th = let val (_$(Const("op =",Type ("fun",[Type ("bool", []),_])) $ A $ B )) = prop_of th in (A,B) end;
   196 
   197 (* ------------------------------------------------------------------------- *)
   198 (* Modified version of the simple version with minimal amount of checking and postprocessing*)
   199 (* ------------------------------------------------------------------------- *)
   200 
   201 fun simple_prove_goal_cterm2 G tacs =
   202   let
   203     fun check None = error "prove_goal: tactic failed"
   204       | check (Some (thm, _)) = (case nprems_of thm of
   205             0 => thm
   206           | i => !result_error_fn thm (string_of_int i ^ " unsolved goals!"))
   207   in check (Seq.pull (EVERY tacs (trivial G))) end;
   208 
   209 (*-------------------------------------------------------------*)
   210 (*-------------------------------------------------------------*)
   211 
   212 fun cert_Trueprop sg t = cterm_of sg (HOLogic.mk_Trueprop t);
   213 
   214 (* ------------------------------------------------------------------------- *)
   215 (*This function proove elementar will be used to generate proofs at runtime*)
   216 (*It is is based on the isabelle function proove_goalw_cterm and is thought to *)
   217 (*prove properties such as a dvd b (essentially) that are only to make at
   218 runtime.*)
   219 (* ------------------------------------------------------------------------- *)
   220 fun prove_elementar sg s fm2 = case s of 
   221   (*"ss" like simplification with simpset*)
   222   "ss" =>
   223     let
   224       val ss = presburger_ss addsimps
   225         [zdvd_iff_zmod_eq_0,unity_coeff_ex]
   226       val ct =  cert_Trueprop sg fm2
   227     in 
   228       simple_prove_goal_cterm2 ct [simp_tac ss 1, TRY (simple_arith_tac 1)] 
   229 
   230     end
   231 
   232   (*"bl" like blast tactic*)
   233   (* Is only used in the harrisons like proof procedure *)
   234   | "bl" =>
   235      let val ct = cert_Trueprop sg fm2
   236      in
   237        simple_prove_goal_cterm2 ct [blast_tac HOL_cs 1]
   238      end
   239 
   240   (*"ed" like Existence disjunctions ...*)
   241   (* Is only used in the harrisons like proof procedure *)
   242   | "ed" =>
   243     let
   244       val ex_disj_tacs =
   245         let
   246           val tac1 = EVERY[REPEAT(resolve_tac [disjI1,disjI2] 1), etac exI 1]
   247           val tac2 = EVERY[etac exE 1, rtac exI 1,
   248             REPEAT(resolve_tac [disjI1,disjI2] 1), assumption 1]
   249 	in [rtac iffI 1,
   250           etac exE 1, REPEAT(EVERY[etac disjE 1, tac1]), tac1,
   251           REPEAT(EVERY[etac disjE 1, tac2]), tac2]
   252         end
   253 
   254       val ct = cert_Trueprop sg fm2
   255     in 
   256       simple_prove_goal_cterm2 ct ex_disj_tacs
   257     end
   258 
   259   | "fa" =>
   260     let val ct = cert_Trueprop sg fm2
   261     in simple_prove_goal_cterm2 ct [simple_arith_tac 1]  
   262 
   263     end
   264 
   265   | "sa" =>
   266     let
   267       val ss = presburger_ss addsimps zadd_ac
   268       val ct = cert_Trueprop sg fm2
   269     in 
   270       simple_prove_goal_cterm2 ct [simp_tac ss 1, TRY (simple_arith_tac 1)]  
   271 
   272     end
   273   (* like Existance Conjunction *)
   274   | "ec" =>
   275     let
   276       val ss = presburger_ss addsimps zadd_ac
   277       val ct = cert_Trueprop sg fm2
   278     in 
   279       simple_prove_goal_cterm2 ct [simp_tac ss 1, TRY (blast_tac HOL_cs 1)]
   280     end
   281 
   282   | "ac" =>
   283     let
   284       val ss = HOL_basic_ss addsimps zadd_ac
   285       val ct = cert_Trueprop sg fm2
   286     in 
   287       simple_prove_goal_cterm2 ct [simp_tac ss 1]
   288     end
   289 
   290   | "lf" =>
   291     let
   292       val ss = presburger_ss addsimps zadd_ac
   293       val ct = cert_Trueprop sg fm2
   294     in 
   295       simple_prove_goal_cterm2 ct [simp_tac ss 1, TRY (simple_arith_tac 1)]  
   296 
   297     end;
   298 
   299 (*=============================================================*)
   300 (*-------------------------------------------------------------*)
   301 (*              The new compact model                          *)
   302 (*-------------------------------------------------------------*)
   303 (*=============================================================*)
   304 
   305 fun thm_of sg decomp t = 
   306     let val (ts,recomb) = decomp t 
   307     in recomb (map (thm_of sg decomp) ts) 
   308     end;
   309 
   310 (*==================================================*)
   311 (*     Compact Version for adjustcoeffeq            *)
   312 (*==================================================*)
   313 
   314 fun decomp_adjustcoeffeq sg x l fm = case fm of
   315     (Const("Not",_)$(Const("op <",_) $(Const("0",_)) $(rt as (Const ("op +", _)$(Const ("op *",_) $    c $ y ) $z )))) => 
   316      let  
   317         val m = l div (dest_numeral c) 
   318         val n = if (x = y) then abs (m) else 1
   319         val xtm = (HOLogic.mk_binop "op *" ((mk_numeral ((m div n)*l) ), x)) 
   320         val rs = if (x = y) 
   321                  then (HOLogic.mk_binrel "op <" (zero,linear_sub [] (mk_numeral n) (HOLogic.mk_binop "op +" ( xtm ,( linear_cmul n z) )))) 
   322                  else HOLogic.mk_binrel "op <" (zero,linear_sub [] one rt )
   323         val ck = cterm_of sg (mk_numeral n)
   324         val cc = cterm_of sg c
   325         val ct = cterm_of sg z
   326         val cx = cterm_of sg y
   327         val pre = prove_elementar sg "lf" 
   328             (HOLogic.mk_binrel "op <" (Const("0",HOLogic.intT),(mk_numeral n)))
   329         val th1 = (pre RS (instantiate' [] [Some ck,Some cc, Some cx, Some ct] (ac_pi_eq)))
   330         in ([], fn [] => [th1,(prove_elementar sg "sa" (HOLogic.mk_eq (snd (qe_get_terms th1) ,rs)))] MRS trans)
   331         end
   332 
   333   |(Const(p,_) $a $( Const ("op +", _)$(Const ("op *",_) $ 
   334       c $ y ) $t )) => 
   335    if (is_arith_rel fm) andalso (x = y) 
   336    then  
   337         let val m = l div (dest_numeral c) 
   338            val k = (if p = "op <" then abs(m) else m)  
   339            val xtm = (HOLogic.mk_binop "op *" ((mk_numeral ((m div k)*l) ), x))
   340            val rs = (HOLogic.mk_binrel p ((linear_cmul k a),(HOLogic.mk_binop "op +" ( xtm ,( linear_cmul k t) )))) 
   341 
   342            val ck = cterm_of sg (mk_numeral k)
   343            val cc = cterm_of sg c
   344            val ct = cterm_of sg t
   345            val cx = cterm_of sg x
   346            val ca = cterm_of sg a
   347 
   348 	   in 
   349 	case p of
   350 	  "op <" => 
   351 	let val pre = prove_elementar sg "lf" 
   352 	    (HOLogic.mk_binrel "op <" (Const("0",HOLogic.intT),(mk_numeral k)))
   353             val th1 = (pre RS (instantiate' [] [Some ck,Some ca,Some cc, Some cx, Some ct] (ac_lt_eq)))
   354 	in ([], fn [] => [th1,(prove_elementar sg "lf" (HOLogic.mk_eq (snd (qe_get_terms th1) ,rs)))] MRS trans)
   355          end
   356 
   357            |"op =" =>
   358 	     let val pre = prove_elementar sg "lf" 
   359 	    (HOLogic.Not $ (HOLogic.mk_binrel "op =" (Const("0",HOLogic.intT),(mk_numeral k))))
   360 	         val th1 = (pre RS(instantiate' [] [Some ck,Some ca,Some cc, Some cx, Some ct] (ac_eq_eq)))
   361 	     in ([], fn [] => [th1,(prove_elementar sg "lf" (HOLogic.mk_eq (snd (qe_get_terms th1) ,rs)))] MRS trans)
   362              end
   363 
   364              |"Divides.op dvd" =>
   365 	       let val pre = prove_elementar sg "lf" 
   366 	   (HOLogic.Not $ (HOLogic.mk_binrel "op =" (Const("0",HOLogic.intT),(mk_numeral k))))
   367                    val th1 = (pre RS (instantiate' [] [Some ck,Some ca,Some cc, Some cx, Some ct]) (ac_dvd_eq))
   368                in ([], fn [] => [th1,(prove_elementar sg "lf" (HOLogic.mk_eq (snd (qe_get_terms th1) ,rs)))] MRS trans)
   369                         
   370                end
   371               end
   372   else ([], fn [] => instantiate' [Some cboolT] [Some (cterm_of sg fm)] refl)
   373 
   374  |( Const ("Not", _) $ p) => ([p], fn [th] => th RS qe_Not)
   375   |( Const ("op &",_) $ p $ q) => ([p,q], fn [th1,th2] => [th1,th2] MRS qe_conjI)
   376   |( Const ("op |",_) $ p $ q) =>([p,q], fn [th1,th2] => [th1,th2] MRS qe_disjI)
   377 
   378   |_ => ([], fn [] => instantiate' [Some cboolT] [Some (cterm_of sg fm)] refl);
   379 
   380 fun proof_of_adjustcoeffeq sg x l = thm_of sg (decomp_adjustcoeffeq sg x l);
   381 
   382 
   383 
   384 (*==================================================*)
   385 (*   Finding rho for modd_minusinfinity             *)
   386 (*==================================================*)
   387 fun rho_for_modd_minf x dlcm sg fm1 =
   388 let
   389     (*Some certified Terms*)
   390     
   391    val ctrue = cterm_of sg HOLogic.true_const
   392    val cfalse = cterm_of sg HOLogic.false_const
   393    val fm = norm_zero_one fm1
   394   in  case fm1 of 
   395       (Const ("Not", _) $ (Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $ (Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z))) => 
   396          if (x=y) andalso (c1= zero) andalso (c2= one) then (instantiate' [Some cboolT] [Some ctrue] (fm_modd_minf))
   397            else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_minf))
   398 
   399       |(Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z)) =>
   400   	   if (is_arith_rel fm) andalso (x=y) andalso (c1= zero) andalso (c2= one) 
   401 	   then (instantiate' [Some cboolT] [Some cfalse] (fm_modd_minf))
   402 	 	 else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_minf)) 
   403 
   404       |(Const("op <",_) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ pm1 $ y ) $ z )) =>
   405            if (y=x) andalso (c1 = zero) then 
   406             if (pm1 = one) then (instantiate' [Some cboolT] [Some cfalse] (fm_modd_minf)) else
   407 	     (instantiate' [Some cboolT] [Some ctrue] (fm_modd_minf))
   408 	    else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_minf))
   409   
   410       |Const ("Not",_) $ (Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   411          if y=x then  let val cz = cterm_of sg (norm_zero_one z)
   412 			  val fm2 = HOLogic.mk_binrel "op =" (HOLogic.mk_binop "Divides.op mod" (dlcm,d),norm_zero_one zero)
   413 	 	      in(instantiate' [] [Some cz ] ((((prove_elementar sg "ss" fm2)) RS(((zdvd_iff_zmod_eq_0)RS sym) RS iffD1) ) RS (not_dvd_modd_minf)))
   414 		      end
   415 		else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_minf))
   416       |(Const("Divides.op dvd",_)$ d $ (db as (Const ("op +",_) $ (Const ("op *",_) $
   417       c $ y ) $ z))) => 
   418          if y=x then  let val cz = cterm_of sg (norm_zero_one z)
   419 			  val fm2 = HOLogic.mk_binrel "op =" (HOLogic.mk_binop "Divides.op mod" (dlcm,d),norm_zero_one zero)
   420 	 	      in(instantiate' [] [Some cz ] ((((prove_elementar sg "ss" fm2)) RS (((zdvd_iff_zmod_eq_0)RS sym) RS iffD1) ) RS (dvd_modd_minf)))
   421 		      end
   422 		else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_minf))
   423 		
   424     
   425    |_ => instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_minf)
   426    end;	 
   427 (*=========================================================================*)
   428 (*=========================================================================*)
   429 fun rho_for_eq_minf x dlcm  sg fm1 =  
   430    let
   431    val fm = norm_zero_one fm1
   432     in  case fm1 of 
   433       (Const ("Not", _) $ (Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $ (Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z))) => 
   434          if  (x=y) andalso (c1=zero) andalso (c2=one) 
   435 	   then (instantiate' [] [Some (cterm_of sg (norm_zero_one z))] (neq_eq_minf))
   436            else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_minf))
   437 
   438       |(Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z)) =>
   439   	   if (is_arith_rel fm) andalso (x=y) andalso ((c1=zero) orelse (c1 = norm_zero_one zero)) andalso ((c2=one) orelse (c1 = norm_zero_one one))
   440 	     then (instantiate' [] [Some (cterm_of sg (norm_zero_one z))] (eq_eq_minf))
   441 	     else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_minf)) 
   442 
   443       |(Const("op <",_) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ pm1 $ y ) $ z )) =>
   444            if (y=x) andalso (c1 =zero) then 
   445             if pm1 = one then (instantiate' [] [Some (cterm_of sg (norm_zero_one z))] (le_eq_minf)) else
   446 	     (instantiate' [] [Some (cterm_of sg (norm_zero_one z))] (len_eq_minf))
   447 	    else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_minf))
   448       |Const ("Not",_) $ (Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   449          if y=x then  let val cd = cterm_of sg (norm_zero_one d)
   450 	 		  val cz = cterm_of sg (norm_zero_one z)
   451 	 	      in(instantiate' [] [Some cd,  Some cz] (not_dvd_eq_minf)) 
   452 		      end
   453 
   454 		else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_minf))
   455 		
   456       |(Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   457          if y=x then  let val cd = cterm_of sg (norm_zero_one d)
   458 	 		  val cz = cterm_of sg (norm_zero_one z)
   459 	 	      in(instantiate' [] [Some cd, Some cz ] (dvd_eq_minf))
   460 		      end
   461 		else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_minf))
   462 
   463       		
   464     |_ => (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_minf))
   465  end;
   466 
   467 (*=====================================================*)
   468 (*=====================================================*)
   469 (*=========== minf proofs with the compact version==========*)
   470 fun decomp_minf_eq x dlcm sg t =  case t of
   471    Const ("op &",_) $ p $q => ([p,q],fn [th1,th2] => [th1,th2] MRS eq_minf_conjI)
   472    |Const ("op |",_) $ p $q => ([p,q],fn [th1,th2] => [th1,th2] MRS eq_minf_disjI)
   473    |_ => ([],fn [] => rho_for_eq_minf x dlcm sg t);
   474 
   475 fun decomp_minf_modd x dlcm sg t = case t of
   476    Const ("op &",_) $ p $q => ([p,q],fn [th1,th2] => [th1,th2] MRS modd_minf_conjI)
   477    |Const ("op |",_) $ p $q => ([p,q],fn [th1,th2] => [th1,th2] MRS modd_minf_disjI)
   478    |_ => ([],fn [] => rho_for_modd_minf x dlcm sg t);
   479 
   480 (* -------------------------------------------------------------*)
   481 (*                    Finding rho for pinf_modd                 *)
   482 (* -------------------------------------------------------------*)
   483 fun rho_for_modd_pinf x dlcm sg fm1 = 
   484 let
   485     (*Some certified Terms*)
   486     
   487   val ctrue = cterm_of sg HOLogic.true_const
   488   val cfalse = cterm_of sg HOLogic.false_const
   489   val fm = norm_zero_one fm1
   490  in  case fm1 of 
   491       (Const ("Not", _) $ (Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $ (Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z))) => 
   492          if ((x=y) andalso (c1= zero) andalso (c2= one))
   493 	 then (instantiate' [Some cboolT] [Some ctrue] (fm_modd_pinf))
   494          else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_pinf))
   495 
   496       |(Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z)) =>
   497   	if ((is_arith_rel fm) andalso (x = y) andalso (c1 = zero)  andalso (c2 = one)) 
   498 	then (instantiate' [Some cboolT] [Some cfalse] (fm_modd_pinf))
   499 	else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_pinf))
   500 
   501       |(Const("op <",_) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ pm1 $ y ) $ z )) =>
   502         if ((y=x) andalso (c1 = zero)) then 
   503           if (pm1 = one) 
   504 	  then (instantiate' [Some cboolT] [Some ctrue] (fm_modd_pinf)) 
   505 	  else (instantiate' [Some cboolT] [Some cfalse] (fm_modd_pinf))
   506 	else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_pinf))
   507   
   508       |Const ("Not",_) $ (Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   509          if y=x then  let val cz = cterm_of sg (norm_zero_one z)
   510 			  val fm2 = HOLogic.mk_binrel "op =" (HOLogic.mk_binop "Divides.op mod" (dlcm,d),norm_zero_one zero)
   511 	 	      in(instantiate' [] [Some cz ] ((((prove_elementar sg "ss" fm2)) RS(((zdvd_iff_zmod_eq_0)RS sym) RS iffD1) ) RS (not_dvd_modd_pinf)))
   512 		      end
   513 		else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_pinf))
   514       |(Const("Divides.op dvd",_)$ d $ (db as (Const ("op +",_) $ (Const ("op *",_) $
   515       c $ y ) $ z))) => 
   516          if y=x then  let val cz = cterm_of sg (norm_zero_one z)
   517 			  val fm2 = HOLogic.mk_binrel "op =" (HOLogic.mk_binop "Divides.op mod" (dlcm,d),norm_zero_one zero)
   518 	 	      in(instantiate' [] [Some cz ] ((((prove_elementar sg "ss" fm2)) RS (((zdvd_iff_zmod_eq_0)RS sym) RS iffD1) ) RS (dvd_modd_pinf)))
   519 		      end
   520 		else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_pinf))
   521 		
   522     
   523    |_ => instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_modd_pinf)
   524    end;	
   525 (* -------------------------------------------------------------*)
   526 (*                    Finding rho for pinf_eq                 *)
   527 (* -------------------------------------------------------------*)
   528 fun rho_for_eq_pinf x dlcm sg fm1 = 
   529   let
   530 					val fm = norm_zero_one fm1
   531     in  case fm1 of 
   532       (Const ("Not", _) $ (Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $ (Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z))) => 
   533          if  (x=y) andalso (c1=zero) andalso (c2=one) 
   534 	   then (instantiate' [] [Some (cterm_of sg (norm_zero_one z))] (neq_eq_pinf))
   535            else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_pinf))
   536 
   537       |(Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z)) =>
   538   	   if (is_arith_rel fm) andalso (x=y) andalso ((c1=zero) orelse (c1 = norm_zero_one zero)) andalso ((c2=one) orelse (c1 = norm_zero_one one))
   539 	     then (instantiate' [] [Some (cterm_of sg (norm_zero_one z))] (eq_eq_pinf))
   540 	     else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_pinf)) 
   541 
   542       |(Const("op <",_) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ pm1 $ y ) $ z )) =>
   543            if (y=x) andalso (c1 =zero) then 
   544             if pm1 = one then (instantiate' [] [Some (cterm_of sg (norm_zero_one z))] (le_eq_pinf)) else
   545 	     (instantiate' [] [Some (cterm_of sg (norm_zero_one z))] (len_eq_pinf))
   546 	    else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_pinf))
   547       |Const ("Not",_) $ (Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   548          if y=x then  let val cd = cterm_of sg (norm_zero_one d)
   549 	 		  val cz = cterm_of sg (norm_zero_one z)
   550 	 	      in(instantiate' [] [Some cd,  Some cz] (not_dvd_eq_pinf)) 
   551 		      end
   552 
   553 		else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_pinf))
   554 		
   555       |(Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   556          if y=x then  let val cd = cterm_of sg (norm_zero_one d)
   557 	 		  val cz = cterm_of sg (norm_zero_one z)
   558 	 	      in(instantiate' [] [Some cd, Some cz ] (dvd_eq_pinf))
   559 		      end
   560 		else (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_pinf))
   561 
   562       		
   563     |_ => (instantiate' [Some cboolT] [Some (cterm_of sg fm)] (fm_eq_pinf))
   564  end;
   565 
   566 
   567 
   568 fun  minf_proof_of_c sg x dlcm t =
   569   let val minf_eqth   = thm_of sg (decomp_minf_eq x dlcm sg) t
   570       val minf_moddth = thm_of sg (decomp_minf_modd x dlcm sg) t
   571   in (minf_eqth, minf_moddth)
   572 end;
   573 
   574 (*=========== pinf proofs with the compact version==========*)
   575 fun decomp_pinf_eq x dlcm sg t = case t of
   576    Const ("op &",_) $ p $q => ([p,q],fn [th1,th2] => [th1,th2] MRS eq_pinf_conjI)
   577    |Const ("op |",_) $ p $q => ([p,q],fn [th1,th2] => [th1,th2] MRS eq_pinf_disjI)
   578    |_ =>([],fn [] => rho_for_eq_pinf x dlcm sg t) ;
   579 
   580 fun decomp_pinf_modd x dlcm sg t =  case t of
   581    Const ("op &",_) $ p $q => ([p,q],fn [th1,th2] => [th1,th2] MRS modd_pinf_conjI)
   582    |Const ("op |",_) $ p $q => ([p,q],fn [th1,th2] => [th1,th2] MRS modd_pinf_disjI)
   583    |_ => ([],fn [] => rho_for_modd_pinf x dlcm sg t);
   584 
   585 fun  pinf_proof_of_c sg x dlcm t =
   586   let val pinf_eqth   = thm_of sg (decomp_pinf_eq x dlcm sg) t
   587       val pinf_moddth = thm_of sg (decomp_pinf_modd x dlcm sg) t
   588   in (pinf_eqth,pinf_moddth)
   589 end;
   590 
   591 
   592 (* ------------------------------------------------------------------------- *)
   593 (* Here we generate the theorem for the Bset Property in the simple direction*)
   594 (* It is just an instantiation*)
   595 (* ------------------------------------------------------------------------- *)
   596 (*
   597 fun bsetproof_of sg (x as Free(xn,xT)) fm bs dlcm   = 
   598   let
   599     val cp = cterm_of sg (absfree (xn,xT,(norm_zero_one fm)))
   600     val cdlcm = cterm_of sg dlcm
   601     val cB = cterm_of sg (list_to_set HOLogic.intT (map norm_zero_one bs))
   602   in instantiate' [] [Some cdlcm,Some cB, Some cp] (bst_thm)
   603 end;
   604 
   605 fun asetproof_of sg (x as Free(xn,xT)) fm ast dlcm = 
   606   let
   607     val cp = cterm_of sg (absfree (xn,xT,(norm_zero_one fm)))
   608     val cdlcm = cterm_of sg dlcm
   609     val cA = cterm_of sg (list_to_set HOLogic.intT (map norm_zero_one ast))
   610   in instantiate' [] [Some cdlcm,Some cA, Some cp] (ast_thm)
   611 end;
   612 *)
   613 
   614 (* For the generation of atomic Theorems*)
   615 (* Prove the premisses on runtime and then make RS*)
   616 (* ------------------------------------------------------------------------- *)
   617 
   618 (*========= this is rho ============*)
   619 fun generate_atomic_not_bst_p sg (x as Free(xn,xT)) fm dlcm B at = 
   620   let
   621     val cdlcm = cterm_of sg dlcm
   622     val cB = cterm_of sg B
   623     val cfma = cterm_of sg (absfree (xn,xT,(norm_zero_one fm)))
   624     val cat = cterm_of sg (norm_zero_one at)
   625   in
   626   case at of 
   627    (Const ("Not", _) $ (Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $ (Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z))) => 
   628       if  (x=y) andalso (c1=zero) andalso (c2=one) 
   629 	 then let val th1 = prove_elementar sg "ss" (Const ("op :",HOLogic.intT --> (HOLogic.mk_setT HOLogic.intT) --> HOLogic.boolT) $ (norm_zero_one (linear_cmul ~1 z)) $ B)
   630 	          val th2 =  prove_elementar sg "ss" (HOLogic.mk_eq ((norm_zero_one (linear_cmul ~1 z)),Const("uminus",HOLogic.intT --> HOLogic.intT) $(norm_zero_one  z)))
   631 		  val th3 = prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (Const("0",HOLogic.intT),dlcm))
   632 	 in  (instantiate' [] [Some cfma]([th3,th1,th2] MRS (not_bst_p_ne)))
   633 	 end
   634          else (instantiate' [] [Some cfma,  Some cdlcm, Some cB,Some cat] (not_bst_p_fm))
   635 
   636    |(Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $(Const ("op +", T) $(Const ("op *",_) $ c2 $ y) $z)) =>
   637      if (is_arith_rel at) andalso (x=y)
   638 	then let val bst_z = norm_zero_one (linear_neg (linear_add [] z (mk_numeral 1)))
   639 	         in let val th1 = prove_elementar sg "ss" (Const ("op :",HOLogic.intT --> (HOLogic.mk_setT HOLogic.intT) --> HOLogic.boolT) $ bst_z $ B)
   640 	          val th2 =  prove_elementar sg "ss" (HOLogic.mk_eq (bst_z,Const("op -",T) $ (Const("uminus",HOLogic.intT --> HOLogic.intT) $(norm_zero_one z)) $ (Const("1",HOLogic.intT))))
   641 		  val th3 = prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (Const("0",HOLogic.intT),dlcm))
   642 	 in  (instantiate' [] [Some cfma] ([th3,th1,th2] MRS (not_bst_p_eq)))
   643 	 end
   644        end
   645          else (instantiate' [] [Some cfma,  Some cdlcm, Some cB,Some cat] (not_bst_p_fm))
   646 
   647    |(Const("op <",_) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ pm1 $ y ) $ z )) =>
   648         if (y=x) andalso (c1 =zero) then 
   649         if pm1 = one then 
   650 	  let val th1 = prove_elementar sg "ss" (Const ("op :",HOLogic.intT --> (HOLogic.mk_setT HOLogic.intT) --> HOLogic.boolT) $ (norm_zero_one (linear_cmul ~1 z)) $ B)
   651               val th2 =  prove_elementar sg "ss" (HOLogic.mk_eq ((norm_zero_one (linear_cmul ~1 z)),Const("uminus",HOLogic.intT --> HOLogic.intT) $(norm_zero_one z)))
   652 	  in  (instantiate' [] [Some cfma,  Some cdlcm]([th1,th2] MRS (not_bst_p_gt)))
   653 	    end
   654 	 else let val th1 = prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (Const("0",HOLogic.intT),dlcm))
   655 	      in (instantiate' [] [Some cfma, Some cB,Some (cterm_of sg (norm_zero_one z))] (th1 RS (not_bst_p_lt)))
   656 	      end
   657       else (instantiate' [] [Some cfma,  Some cdlcm, Some cB,Some cat] (not_bst_p_fm))
   658 
   659    |Const ("Not",_) $ (Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   660       if y=x then  
   661            let val cz = cterm_of sg (norm_zero_one z)
   662 	       val th1 = (prove_elementar sg "ss"  (HOLogic.mk_binrel "op =" (HOLogic.mk_binop "Divides.op mod" (dlcm,d),norm_zero_one zero))) RS (((zdvd_iff_zmod_eq_0)RS sym) RS iffD1)
   663  	     in (instantiate' []  [Some cfma, Some cB,Some cz] (th1 RS (not_bst_p_ndvd)))
   664 	     end
   665       else (instantiate' [] [Some cfma,  Some cdlcm, Some cB,Some cat] (not_bst_p_fm))
   666 
   667    |(Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   668        if y=x then  
   669 	 let val cz = cterm_of sg (norm_zero_one z)
   670 	     val th1 = (prove_elementar sg "ss"  (HOLogic.mk_binrel "op =" (HOLogic.mk_binop "Divides.op mod" (dlcm,d),norm_zero_one zero))) RS (((zdvd_iff_zmod_eq_0)RS sym) RS iffD1)
   671  	    in (instantiate' []  [Some cfma,Some cB,Some cz] (th1 RS (not_bst_p_dvd)))
   672 	  end
   673       else (instantiate' [] [Some cfma,  Some cdlcm, Some cB,Some cat] (not_bst_p_fm))
   674       		
   675    |_ => (instantiate' [] [Some cfma,  Some cdlcm, Some cB,Some cat] (not_bst_p_fm))
   676       		
   677     end;
   678     
   679 
   680 (* ------------------------------------------------------------------------- *)    
   681 (* Main interpretation function for this backwards dirction*)
   682 (* if atomic do generate atomis formulae else Construct theorems and then make RS with the construction theorems*)
   683 (*Help Function*)
   684 (* ------------------------------------------------------------------------- *)
   685 
   686 (*==================== Proof with the compact version   *)
   687 
   688 fun decomp_nbstp sg x dlcm B fm t = case t of 
   689    Const("op &",_) $ ls $ rs => ([ls,rs],fn [th1,th2] => [th1,th2] MRS not_bst_p_conjI )
   690   |Const("op |",_) $ ls $ rs => ([ls,rs],fn [th1,th2] => [th1,th2] MRS not_bst_p_disjI)
   691   |_ => ([], fn [] => generate_atomic_not_bst_p sg x fm dlcm B t);
   692 
   693 fun not_bst_p_proof_of_c sg (x as Free(xn,xT)) fm dlcm B t =
   694   let 
   695        val th =  thm_of sg (decomp_nbstp sg x dlcm (list_to_set xT (map norm_zero_one B)) fm) t
   696       val fma = absfree (xn,xT, norm_zero_one fm)
   697   in let val th1 =  prove_elementar sg "ss"  (HOLogic.mk_eq (fma,fma))
   698      in [th,th1] MRS (not_bst_p_Q_elim)
   699      end
   700   end;
   701 
   702 
   703 (* ------------------------------------------------------------------------- *)    
   704 (* Protokol interpretation function for the backwards direction for cooper's Theorem*)
   705 
   706 (* For the generation of atomic Theorems*)
   707 (* Prove the premisses on runtime and then make RS*)
   708 (* ------------------------------------------------------------------------- *)
   709 (*========= this is rho ============*)
   710 fun generate_atomic_not_ast_p sg (x as Free(xn,xT)) fm dlcm A at = 
   711   let
   712     val cdlcm = cterm_of sg dlcm
   713     val cA = cterm_of sg A
   714     val cfma = cterm_of sg (absfree (xn,xT,(norm_zero_one fm)))
   715     val cat = cterm_of sg (norm_zero_one at)
   716   in
   717   case at of 
   718    (Const ("Not", _) $ (Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $ (Const ("op +", _) $(Const ("op *",_) $ c2 $ y) $z))) => 
   719       if  (x=y) andalso (c1=zero) andalso (c2=one) 
   720 	 then let val th1 = prove_elementar sg "ss" (Const ("op :",HOLogic.intT --> (HOLogic.mk_setT HOLogic.intT) --> HOLogic.boolT) $ (norm_zero_one (linear_cmul ~1 z)) $ A)
   721 	          val th2 =  prove_elementar sg "ss" (HOLogic.mk_eq ((norm_zero_one (linear_cmul ~1 z)),Const("uminus",HOLogic.intT --> HOLogic.intT) $(norm_zero_one  z)))
   722 		  val th3 = prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (Const("0",HOLogic.intT),dlcm))
   723 	 in  (instantiate' [] [Some cfma]([th3,th1,th2] MRS (not_ast_p_ne)))
   724 	 end
   725          else (instantiate' [] [Some cfma,  Some cdlcm, Some cA,Some cat] (not_ast_p_fm))
   726 
   727    |(Const("op =",Type ("fun",[Type ("IntDef.int", []),_])) $ c1 $(Const ("op +", T) $(Const ("op *",_) $ c2 $ y) $z)) =>
   728      if (is_arith_rel at) andalso (x=y)
   729 	then let val ast_z = norm_zero_one (linear_sub [] one z )
   730 	         val th1 = prove_elementar sg "ss" (Const ("op :",HOLogic.intT --> (HOLogic.mk_setT HOLogic.intT) --> HOLogic.boolT) $ ast_z $ A)
   731 	         val th2 =  prove_elementar sg "ss" (HOLogic.mk_eq (ast_z,Const("op +",T) $ (Const("uminus",HOLogic.intT --> HOLogic.intT) $(norm_zero_one z)) $ (Const("1",HOLogic.intT))))
   732 		 val th3 = prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (Const("0",HOLogic.intT),dlcm))
   733 	 in  (instantiate' [] [Some cfma] ([th3,th1,th2] MRS (not_ast_p_eq)))
   734        end
   735          else (instantiate' [] [Some cfma,  Some cdlcm, Some cA,Some cat] (not_ast_p_fm))
   736 
   737    |(Const("op <",_) $ c1 $(Const ("op +", _) $(Const ("op *",_) $ pm1 $ y ) $ z )) =>
   738         if (y=x) andalso (c1 =zero) then 
   739         if pm1 = (mk_numeral ~1) then 
   740 	  let val th1 = prove_elementar sg "ss" (Const ("op :",HOLogic.intT --> (HOLogic.mk_setT HOLogic.intT) --> HOLogic.boolT) $ (norm_zero_one z) $ A)
   741               val th2 =  prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (zero,dlcm))
   742 	  in  (instantiate' [] [Some cfma]([th2,th1] MRS (not_ast_p_lt)))
   743 	    end
   744 	 else let val th1 = prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (Const("0",HOLogic.intT),dlcm))
   745 	      in (instantiate' [] [Some cfma, Some cA,Some (cterm_of sg (norm_zero_one z))] (th1 RS (not_ast_p_gt)))
   746 	      end
   747       else (instantiate' [] [Some cfma,  Some cdlcm, Some cA,Some cat] (not_ast_p_fm))
   748 
   749    |Const ("Not",_) $ (Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   750       if y=x then  
   751            let val cz = cterm_of sg (norm_zero_one z)
   752 	       val th1 = (prove_elementar sg "ss"  (HOLogic.mk_binrel "op =" (HOLogic.mk_binop "Divides.op mod" (dlcm,d),norm_zero_one zero))) RS (((zdvd_iff_zmod_eq_0)RS sym) RS iffD1)
   753  	     in (instantiate' []  [Some cfma, Some cA,Some cz] (th1 RS (not_ast_p_ndvd)))
   754 	     end
   755       else (instantiate' [] [Some cfma,  Some cdlcm, Some cA,Some cat] (not_ast_p_fm))
   756 
   757    |(Const("Divides.op dvd",_)$ d $ (Const ("op +",_) $ (Const ("op *",_) $ c $ y ) $ z)) => 
   758        if y=x then  
   759 	 let val cz = cterm_of sg (norm_zero_one z)
   760 	     val th1 = (prove_elementar sg "ss"  (HOLogic.mk_binrel "op =" (HOLogic.mk_binop "Divides.op mod" (dlcm,d),norm_zero_one zero))) RS (((zdvd_iff_zmod_eq_0)RS sym) RS iffD1)
   761  	    in (instantiate' []  [Some cfma,Some cA,Some cz] (th1 RS (not_ast_p_dvd)))
   762 	  end
   763       else (instantiate' [] [Some cfma,  Some cdlcm, Some cA,Some cat] (not_ast_p_fm))
   764       		
   765    |_ => (instantiate' [] [Some cfma,  Some cdlcm, Some cA,Some cat] (not_ast_p_fm))
   766       		
   767     end;
   768 
   769 (* ------------------------------------------------------------------------ *)
   770 (* Main interpretation function for this backwards dirction*)
   771 (* if atomic do generate atomis formulae else Construct theorems and then make RS with the construction theorems*)
   772 (*Help Function*)
   773 (* ------------------------------------------------------------------------- *)
   774 
   775 fun decomp_nastp sg x dlcm A fm t = case t of 
   776    Const("op &",_) $ ls $ rs => ([ls,rs],fn [th1,th2] => [th1,th2] MRS not_ast_p_conjI )
   777   |Const("op |",_) $ ls $ rs => ([ls,rs],fn [th1,th2] => [th1,th2] MRS not_ast_p_disjI)
   778   |_ => ([], fn [] => generate_atomic_not_ast_p sg x fm dlcm A t);
   779 
   780 fun not_ast_p_proof_of_c sg (x as Free(xn,xT)) fm dlcm A t =
   781   let 
   782        val th =  thm_of sg (decomp_nastp sg x dlcm (list_to_set xT (map norm_zero_one A)) fm) t
   783       val fma = absfree (xn,xT, norm_zero_one fm)
   784   in let val th1 =  prove_elementar sg "ss"  (HOLogic.mk_eq (fma,fma))
   785      in [th,th1] MRS (not_ast_p_Q_elim)
   786      end
   787   end;
   788 
   789 
   790 (* -------------------------------*)
   791 (* Finding rho and beta for evalc *)
   792 (* -------------------------------*)
   793 
   794 fun rho_for_evalc sg at = case at of  
   795     (Const (p,_) $ s $ t) =>(  
   796     case assoc (operations,p) of 
   797         Some f => 
   798            ((if (f ((dest_numeral s),(dest_numeral t))) 
   799              then prove_elementar sg "ss" (HOLogic.mk_eq(at,HOLogic.true_const)) 
   800              else prove_elementar sg "ss" (HOLogic.mk_eq(at, HOLogic.false_const)))  
   801 		   handle _ => instantiate' [Some cboolT] [Some (cterm_of sg at)] refl)
   802         | _ => instantiate' [Some cboolT] [Some (cterm_of sg at)] refl )
   803      |Const("Not",_)$(Const (p,_) $ s $ t) =>(  
   804        case assoc (operations,p) of 
   805          Some f => 
   806            ((if (f ((dest_numeral s),(dest_numeral t))) 
   807              then prove_elementar sg "ss" (HOLogic.mk_eq(at, HOLogic.false_const))  
   808              else prove_elementar sg "ss" (HOLogic.mk_eq(at,HOLogic.true_const)))  
   809 		      handle _ => instantiate' [Some cboolT] [Some (cterm_of sg at)] refl) 
   810          | _ => instantiate' [Some cboolT] [Some (cterm_of sg at)] refl ) 
   811      | _ =>   instantiate' [Some cboolT] [Some (cterm_of sg at)] refl;
   812 
   813 
   814 (*=========================================================*)
   815 fun decomp_evalc sg t = case t of
   816    (Const("op &",_)$A$B) => ([A,B], fn [th1,th2] => [th1,th2] MRS qe_conjI)
   817    |(Const("op |",_)$A$B) => ([A,B], fn [th1,th2] => [th1,th2] MRS qe_disjI)
   818    |(Const("op -->",_)$A$B) => ([A,B], fn [th1,th2] => [th1,th2] MRS qe_impI)
   819    |(Const("op =", Type ("fun",[Type ("bool", []),_]))$A$B) => ([A,B], fn [th1,th2] => [th1,th2] MRS qe_eqI)
   820    |_ => ([], fn [] => rho_for_evalc sg t);
   821 
   822 
   823 fun proof_of_evalc sg fm = thm_of sg (decomp_evalc sg) fm;
   824 
   825 (*==================================================*)
   826 (*     Proof of linform with the compact model      *)
   827 (*==================================================*)
   828 
   829 
   830 fun decomp_linform sg vars t = case t of
   831    (Const("op &",_)$A$B) => ([A,B], fn [th1,th2] => [th1,th2] MRS qe_conjI)
   832    |(Const("op |",_)$A$B) => ([A,B], fn [th1,th2] => [th1,th2] MRS qe_disjI)
   833    |(Const("op -->",_)$A$B) => ([A,B], fn [th1,th2] => [th1,th2] MRS qe_impI)
   834    |(Const("op =", Type ("fun",[Type ("bool", []),_]))$A$B) => ([A,B], fn [th1,th2] => [th1,th2] MRS qe_eqI)
   835    |(Const("Not",_)$p) => ([p],fn [th] => th RS qe_Not)
   836    |(Const("Divides.op dvd",_)$d$r) => 
   837      if is_numeral d then ([], fn [] => (prove_elementar sg "lf" (HOLogic.mk_eq (r, lint vars r))) RS (instantiate' [] [None , None, Some (cterm_of sg d)](linearize_dvd)))
   838      else (warning "Nonlinear Term --- Non numeral leftside at dvd";
   839        raise COOPER)
   840    |_ => ([], fn [] => prove_elementar sg "lf" (HOLogic.mk_eq (t, linform vars t)));
   841 
   842 fun proof_of_linform sg vars f = thm_of sg (decomp_linform sg vars) f;
   843 
   844 (* ------------------------------------------------------------------------- *)
   845 (* Interpretaion of Protocols of the cooper procedure : minusinfinity version*)
   846 (* ------------------------------------------------------------------------- *)
   847 fun coopermi_proof_of sg (x as Free(xn,xT)) fm B dlcm =
   848   (* Get the Bset thm*)
   849   let val (minf_eqth, minf_moddth) = minf_proof_of_c sg x dlcm fm 
   850       val dpos = prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (zero,dlcm));
   851       val nbstpthm = not_bst_p_proof_of_c sg x fm dlcm B fm
   852   in (dpos,minf_eqth,nbstpthm,minf_moddth)
   853 end;
   854 
   855 (* ------------------------------------------------------------------------- *)
   856 (* Interpretaion of Protocols of the cooper procedure : plusinfinity version *)
   857 (* ------------------------------------------------------------------------- *)
   858 fun cooperpi_proof_of sg (x as Free(xn,xT)) fm A dlcm =
   859   let val (pinf_eqth,pinf_moddth) = pinf_proof_of_c sg x dlcm fm
   860       val dpos = prove_elementar sg "ss" (HOLogic.mk_binrel "op <" (zero,dlcm));
   861       val nastpthm = not_ast_p_proof_of_c sg x fm dlcm A fm
   862   in (dpos,pinf_eqth,nastpthm,pinf_moddth)
   863 end;
   864 
   865 (* ------------------------------------------------------------------------- *)
   866 (* Interpretaion of Protocols of the cooper procedure : full version*)
   867 (* ------------------------------------------------------------------------- *)
   868 fun cooper_thm sg s (x as Free(xn,xT)) cfm dlcm ast bst= case s of
   869   "pi" => let val (dpsthm,pinf_eqth,nbpth,pinf_moddth) = cooperpi_proof_of sg x cfm ast dlcm 
   870 	      in [dpsthm,pinf_eqth,nbpth,pinf_moddth] MRS (cppi_eq)
   871            end
   872   |"mi" => let val (dpsthm,minf_eqth,nbpth,minf_moddth) = coopermi_proof_of sg x cfm bst dlcm
   873 	       in [dpsthm,minf_eqth,nbpth,minf_moddth] MRS (cpmi_eq)
   874                 end
   875  |_ => error "parameter error";
   876 
   877 (* ------------------------------------------------------------------------- *)
   878 (* This function should evoluate to the end prove Procedure for one quantifier elimination for Presburger arithmetic*)
   879 (* It shoud be plugged in the qfnp argument of the quantifier elimination proof function*)
   880 (* ------------------------------------------------------------------------- *)
   881 
   882 val (timef:(unit->thm) -> thm,prtime,time_reset) = gen_timer();
   883 val (timef2:(unit->thm) -> thm,prtime2,time_reset2) = gen_timer();
   884 
   885 fun cooper_prv sg (x as Free(xn,xT)) efm = let 
   886    (* lfm_thm : efm = linearized form of efm*)
   887    val lfm_thm = proof_of_linform sg [xn] efm
   888    (*efm2 is the linearized form of efm *) 
   889    val efm2 = snd(qe_get_terms lfm_thm)
   890    (* l is the lcm of all coefficients of x *)
   891    val l = formlcm x efm2
   892    (*ac_thm: efm = efm2 with adjusted coefficients of x *)
   893    val ac_thm = [lfm_thm , (proof_of_adjustcoeffeq sg x l efm2)] MRS trans
   894    (* fm is efm2 with adjusted coefficients of x *)
   895    val fm = snd (qe_get_terms ac_thm)
   896   (* cfm is l dvd x & fm' where fm' is fm where l*x is replaced by x*)
   897    val  cfm = unitycoeff x fm
   898    (*afm is fm where c*x is replaced by 1*x or -1*x *)
   899    val afm = adjustcoeff x l fm
   900    (* P = %x.afm*)
   901    val P = absfree(xn,xT,afm)
   902    (* This simpset allows the elimination of the sets in bex {1..d} *)
   903    val ss = presburger_ss addsimps
   904      [simp_from_to] delsimps [P_eqtrue, P_eqfalse, bex_triv, insert_iff]
   905    (* uth : EX x.P(l*x) = EX x. l dvd x & P x*)
   906    val uth = instantiate' [] [Some (cterm_of sg P) , Some (cterm_of sg (mk_numeral l))] (unity_coeff_ex)
   907    (* e_ac_thm : Ex x. efm = EX x. fm*)
   908    val e_ac_thm = (forall_intr (cterm_of sg x) ac_thm) COMP (qe_exI)
   909    (* A and B set of the formula*)
   910    val A = aset x cfm
   911    val B = bset x cfm
   912    (* the divlcm (delta) of the formula*)
   913    val dlcm = mk_numeral (divlcm x cfm)
   914    (* Which set is smaller to generate the (hoepfully) shorter proof*)
   915    val cms = if ((length A) < (length B )) then "pi" else "mi"
   916    val _ = if cms = "pi" then writeln "Plusinfinity" else writeln "Minusinfinity"
   917    (* synthesize the proof of cooper's theorem*)
   918     (* cp_thm: EX x. cfm = Q*)
   919    val cp_thm = timef ( fn () => cooper_thm sg cms x cfm dlcm A B)
   920    (* Exxpand the right hand side to get rid of EX j : {1..d} to get a huge disjunction*)
   921    (* exp_cp_thm: EX x.cfm = Q' , where Q' is a simplified version of Q*)
   922    val _ = prth cp_thm
   923    val _ = writeln "Expanding the bounded EX..."
   924    val exp_cp_thm = timef2 (fn () => refl RS (simplify ss (cp_thm RSN (2,trans))))
   925    val _ = writeln "Expanded"
   926    (* lsuth = EX.P(l*x) ; rsuth = EX x. l dvd x & P x*)
   927    val (lsuth,rsuth) = qe_get_terms (uth)
   928    (* lseacth = EX x. efm; rseacth = EX x. fm*)
   929    val (lseacth,rseacth) = qe_get_terms(e_ac_thm)
   930    (* lscth = EX x. cfm; rscth = Q' *)
   931    val (lscth,rscth) = qe_get_terms (exp_cp_thm)
   932    (* u_c_thm: EX x. P(l*x) = Q'*)
   933    val  u_c_thm = [([uth,prove_elementar sg "ss" (HOLogic.mk_eq (rsuth,lscth))] MRS trans),exp_cp_thm] MRS trans
   934    (* result: EX x. efm = Q'*)
   935  in  ([e_ac_thm,[(prove_elementar sg "ss" (HOLogic.mk_eq (rseacth,lsuth))),u_c_thm] MRS trans] MRS trans)
   936    end
   937 |cooper_prv _ _ _ =  error "Parameters format";
   938 
   939 (* **************************************** *)
   940 (*    An Other Version of cooper proving    *)
   941 (*     by giving a withness for EX          *)
   942 (* **************************************** *)
   943 
   944 
   945 
   946 fun cooper_prv_w sg (x as Free(xn,xT)) efm = let 
   947    (* lfm_thm : efm = linearized form of efm*)
   948    val lfm_thm = proof_of_linform sg [xn] efm
   949    (*efm2 is the linearized form of efm *) 
   950    val efm2 = snd(qe_get_terms lfm_thm)
   951    (* l is the lcm of all coefficients of x *)
   952    val l = formlcm x efm2
   953    (*ac_thm: efm = efm2 with adjusted coefficients of x *)
   954    val ac_thm = [lfm_thm , (proof_of_adjustcoeffeq sg x l efm2)] MRS trans
   955    (* fm is efm2 with adjusted coefficients of x *)
   956    val fm = snd (qe_get_terms ac_thm)
   957   (* cfm is l dvd x & fm' where fm' is fm where l*x is replaced by x*)
   958    val  cfm = unitycoeff x fm
   959    (*afm is fm where c*x is replaced by 1*x or -1*x *)
   960    val afm = adjustcoeff x l fm
   961    (* P = %x.afm*)
   962    val P = absfree(xn,xT,afm)
   963    (* This simpset allows the elimination of the sets in bex {1..d} *)
   964    val ss = presburger_ss addsimps
   965      [simp_from_to] delsimps [P_eqtrue, P_eqfalse, bex_triv, insert_iff]
   966    (* uth : EX x.P(l*x) = EX x. l dvd x & P x*)
   967    val uth = instantiate' [] [Some (cterm_of sg P) , Some (cterm_of sg (mk_numeral l))] (unity_coeff_ex)
   968    (* e_ac_thm : Ex x. efm = EX x. fm*)
   969    val e_ac_thm = (forall_intr (cterm_of sg x) ac_thm) COMP (qe_exI)
   970    (* lsuth = EX.P(l*x) ; rsuth = EX x. l dvd x & P x*)
   971    val (lsuth,rsuth) = qe_get_terms (uth)
   972    (* lseacth = EX x. efm; rseacth = EX x. fm*)
   973    val (lseacth,rseacth) = qe_get_terms(e_ac_thm)
   974 
   975    val (w,rs) = cooper_w [] cfm
   976    val exp_cp_thm =  case w of 
   977      (* FIXME - e_ac_thm just tipped to test syntactical correctness of the program!!!!*)
   978     Some n =>  e_ac_thm (* Prove cfm (n) and use exI and then Eq_TrueI*)
   979    |_ => let 
   980     (* A and B set of the formula*)
   981     val A = aset x cfm
   982     val B = bset x cfm
   983     (* the divlcm (delta) of the formula*)
   984     val dlcm = mk_numeral (divlcm x cfm)
   985     (* Which set is smaller to generate the (hoepfully) shorter proof*)
   986     val cms = if ((length A) < (length B )) then "pi" else "mi"
   987     (* synthesize the proof of cooper's theorem*)
   988      (* cp_thm: EX x. cfm = Q*)
   989     val cp_thm = cooper_thm sg cms x cfm dlcm A B
   990      (* Exxpand the right hand side to get rid of EX j : {1..d} to get a huge disjunction*)
   991     (* exp_cp_thm: EX x.cfm = Q' , where Q' is a simplified version of Q*)
   992     in refl RS (simplify ss (cp_thm RSN (2,trans)))
   993     end
   994    (* lscth = EX x. cfm; rscth = Q' *)
   995    val (lscth,rscth) = qe_get_terms (exp_cp_thm)
   996    (* u_c_thm: EX x. P(l*x) = Q'*)
   997    val  u_c_thm = [([uth,prove_elementar sg "ss" (HOLogic.mk_eq (rsuth,lscth))] MRS trans),exp_cp_thm] MRS trans
   998    (* result: EX x. efm = Q'*)
   999  in  ([e_ac_thm,[(prove_elementar sg "ss" (HOLogic.mk_eq (rseacth,lsuth))),u_c_thm] MRS trans] MRS trans)
  1000    end
  1001 |cooper_prv_w _ _ _ =  error "Parameters format";
  1002 
  1003 
  1004 
  1005 fun decomp_cnnf sg lfnp P = case P of 
  1006      Const ("op &",_) $ p $q => ([p,q] , fn [th1,th2] => [th1,th2] MRS qe_conjI )
  1007    |Const ("op |",_) $ p $q => ([p,q] , fn [th1,th2] => [th1,th2] MRS  qe_disjI)
  1008    |Const ("Not",_) $ (Const("Not",_) $ p) => ([p], fn [th] => th RS nnf_nn)
  1009    |Const("Not",_) $ (Const(opn,T) $ p $ q) => 
  1010      if opn = "op |" 
  1011       then case (p,q) of 
  1012          (A as (Const ("op &",_) $ r $ s),B as (Const ("op &",_) $ r1 $ t)) =>
  1013           if r1 = negate r 
  1014           then  ([r,HOLogic.Not$s,r1,HOLogic.Not$t],fn [th1_1,th1_2,th2_1,th2_2] => [[th1_1,th1_1] MRS qe_conjI,[th2_1,th2_2] MRS qe_conjI] MRS nnf_sdj)
  1015 
  1016           else ([HOLogic.Not $ p,HOLogic.Not $ q ], fn [th1,th2] => [th1,th2] MRS nnf_ndj)
  1017         |(_,_) => ([HOLogic.Not $ p,HOLogic.Not $ q ], fn [th1,th2] => [th1,th2] MRS nnf_ndj)
  1018       else (
  1019          case (opn,T) of 
  1020            ("op &",_) => ([HOLogic.Not $ p,HOLogic.Not $ q ], fn [th1,th2] =>[th1,th2] MRS nnf_ncj )
  1021            |("op -->",_) => ([p,HOLogic.Not $ q ], fn [th1,th2] =>[th1,th2] MRS nnf_nim )
  1022            |("op =",Type ("fun",[Type ("bool", []),_])) => 
  1023            ([HOLogic.conj $ p $ (HOLogic.Not $ q),HOLogic.conj $ (HOLogic.Not $ p) $ q], fn [th1,th2] => [th1,th2] MRS nnf_neq)
  1024             |(_,_) => ([], fn [] => lfnp P)
  1025 )
  1026 
  1027    |(Const ("op -->",_) $ p $ q) => ([HOLogic.Not$p,q], fn [th1,th2] => [th1,th2] MRS nnf_im)
  1028 
  1029    |(Const ("op =", Type ("fun",[Type ("bool", []),_])) $ p $ q) =>
  1030      ([HOLogic.conj $ p $ q,HOLogic.conj $ (HOLogic.Not $ p) $ (HOLogic.Not $ q) ], fn [th1,th2] =>[th1,th2] MRS nnf_eq )
  1031    |_ => ([], fn [] => lfnp P);
  1032 
  1033 
  1034 
  1035 
  1036 fun proof_of_cnnf sg p lfnp = 
  1037  let val th1 = thm_of sg (decomp_cnnf sg lfnp) p
  1038      val rs = snd(qe_get_terms th1)
  1039      val th2 = prove_elementar sg "ss" (HOLogic.mk_eq(rs,simpl rs))
  1040   in [th1,th2] MRS trans
  1041   end;
  1042 
  1043 end;
  1044