src/HOL/Tools/Qelim/presburger.ML
changeset 23499 7e27947d92d7
parent 23488 342029af73d1
child 23530 438c5d2db482
equal deleted inserted replaced
23498:4db8aa43076c 23499:7e27947d92d7
     1 
       
     2 (*  Title:      HOL/Tools/Presburger/presburger.ML
     1 (*  Title:      HOL/Tools/Presburger/presburger.ML
     3     ID:         $Id$
     2     ID:         $Id$
     4     Author:     Amine Chaieb, TU Muenchen
     3     Author:     Amine Chaieb, TU Muenchen
     5 *)
     4 *)
     6 
     5 
     7 signature PRESBURGER =
     6 signature PRESBURGER =
     8  sig
     7 sig
     9   val cooper_tac: bool -> thm list -> thm list -> Proof.context -> int -> Tactical.tactic
     8   val cooper_tac: bool -> thm list -> thm list -> Proof.context -> int -> tactic
    10 end;
     9 end;
    11 
    10 
    12 structure Presburger : PRESBURGER = 
    11 structure Presburger : PRESBURGER = 
    13 struct
    12 struct
    14 
    13 
    15 open Conv;
    14 open Conv;
    16 val comp_ss = HOL_ss addsimps @{thms "Groebner_Basis.comp_arith"};
    15 val comp_ss = HOL_ss addsimps @{thms "Groebner_Basis.comp_arith"};
    17 
    16 
    18 fun strip_imp_cprems ct = 
    17 fun strip_objimp ct =
    19  case term_of ct of 
    18   (case Thm.term_of ct of
    20   Const ("==>", _) $ _ $ _ => Thm.dest_arg1 ct :: strip_imp_cprems (Thm.dest_arg ct)
    19     Const ("op -->", _) $ _ $ _ =>
    21 | _ => [];
    20       let val (A, B) = Thm.dest_binop ct
    22 
    21       in A :: strip_objimp B end
    23 val cprems_of = strip_imp_cprems o cprop_of;
    22   | _ => [ct]);
    24 
       
    25 fun strip_objimp ct = 
       
    26  case term_of ct of 
       
    27   Const ("op -->", _) $ _ $ _ => Thm.dest_arg1 ct :: strip_objimp (Thm.dest_arg ct)
       
    28 | _ => [ct];
       
    29 
    23 
    30 fun strip_objall ct = 
    24 fun strip_objall ct = 
    31  case term_of ct of 
    25  case term_of ct of 
    32   Const ("All", _) $ Abs (xn,xT,p) => 
    26   Const ("All", _) $ Abs (xn,xT,p) => 
    33    let val (a,(v,t')) = (apsnd (Thm.dest_abs (SOME xn)) o Thm.dest_comb) ct
    27    let val (a,(v,t')) = (apsnd (Thm.dest_abs (SOME xn)) o Thm.dest_comb) ct
    37 
    31 
    38 local
    32 local
    39   val all_maxscope_ss = 
    33   val all_maxscope_ss = 
    40      HOL_basic_ss addsimps map (fn th => th RS sym) @{thms "all_simps"}
    34      HOL_basic_ss addsimps map (fn th => th RS sym) @{thms "all_simps"}
    41 in
    35 in
    42 fun thin_prems_tac P i =  simp_tac all_maxscope_ss i THEN
    36 fun thin_prems_tac P = simp_tac all_maxscope_ss THEN'
    43   (fn st => case try (nth (cprems_of st)) (i - 1) of
    37   CSUBGOAL (fn (p', i) =>
    44     NONE => no_tac st
       
    45   | SOME p' => 
       
    46     let
    38     let
    47      val (qvs, p) = strip_objall (Thm.dest_arg p')
    39      val (qvs, p) = strip_objall (Thm.dest_arg p')
    48      val (ps, c) = split_last (strip_objimp p)
    40      val (ps, c) = split_last (strip_objimp p)
    49      val qs = filter P ps
    41      val qs = filter P ps
    50      val q = if P c then c else @{cterm "False"}
    42      val q = if P c then c else @{cterm "False"}
    52          (fold_rev (fn p => fn q => Thm.capply (Thm.capply @{cterm "op -->"} p) q) qs q)
    44          (fold_rev (fn p => fn q => Thm.capply (Thm.capply @{cterm "op -->"} p) q) qs q)
    53      val g = Thm.capply (Thm.capply @{cterm "op ==>"} (Thm.capply @{cterm "Trueprop"} ng)) p'
    45      val g = Thm.capply (Thm.capply @{cterm "op ==>"} (Thm.capply @{cterm "Trueprop"} ng)) p'
    54      val ntac = (case qs of [] => q aconvc @{cterm "False"}
    46      val ntac = (case qs of [] => q aconvc @{cterm "False"}
    55                          | _ => false)
    47                          | _ => false)
    56     in 
    48     in 
    57     if ntac then no_tac st
    49     if ntac then no_tac
    58       else rtac (Goal.prove_internal [] g (K (blast_tac HOL_cs 1))) i st 
    50       else rtac (Goal.prove_internal [] g (K (blast_tac HOL_cs 1))) i
    59     end)
    51     end)
    60 end;
    52 end;
    61 
    53 
    62 local
    54 local
    63  fun ty cts t = 
    55  fun ty cts t = 
    64  if not (typ_of (ctyp_of_term t) mem [HOLogic.intT, HOLogic.natT]) then false 
    56  if not (typ_of (ctyp_of_term t) mem [HOLogic.intT, HOLogic.natT]) then false 
    65     else case term_of t of 
    57     else case term_of t of 
    66       c$_$_ => not (member (op aconv) cts c)
    58       c$_$_ => not (member (op aconv) cts c)
    67     | c$_ => not (member (op aconv) cts c)
    59     | c$_ => not (member (op aconv) cts c)
    68     | c => not (member (op aconv) cts c)
    60     | c => not (member (op aconv) cts c)
    69     | _ => true
       
    70 
    61 
    71  val term_constants =
    62  val term_constants =
    72   let fun h acc t = case t of
    63   let fun h acc t = case t of
    73     Const _ => insert (op aconv) t acc
    64     Const _ => insert (op aconv) t acc
    74   | a$b => h (h acc a) b
    65   | a$b => h (h acc a) b
    90   | Abs(_,_,_) => Thm.dest_abs NONE t ||> h acc |> uncurry (remove (op aconvc))
    81   | Abs(_,_,_) => Thm.dest_abs NONE t ||> h acc |> uncurry (remove (op aconvc))
    91   | _ => acc
    82   | _ => acc
    92  in h [] ct end
    83  in h [] ct end
    93 end;
    84 end;
    94 
    85 
    95 fun generalize_tac ctxt f i st = 
    86 fun generalize_tac f = CSUBGOAL (fn (p, i) => PRIMITIVE (fn st =>
    96  case try (nth (cprems_of st)) (i - 1) of
    87  let 
    97     NONE => all_tac st
       
    98   | SOME p => 
       
    99    let 
       
   100    fun all T = Drule.cterm_rule (instantiate' [SOME T] []) @{cpat "all"}
    88    fun all T = Drule.cterm_rule (instantiate' [SOME T] []) @{cpat "all"}
   101    fun gen x t = Thm.capply (all (ctyp_of_term x)) (Thm.cabs x t)
    89    fun gen x t = Thm.capply (all (ctyp_of_term x)) (Thm.cabs x t)
   102    val ts = sort (fn (a,b) => Term.fast_term_ord (term_of a, term_of b)) (f p)
    90    val ts = sort (fn (a,b) => Term.fast_term_ord (term_of a, term_of b)) (f p)
   103    val p' = fold_rev gen ts p
    91    val p' = fold_rev gen ts p
   104  in Seq.of_list [implies_intr p' (implies_elim st (fold forall_elim ts (assume p')))]
    92  in implies_intr p' (implies_elim st (fold forall_elim ts (assume p'))) end));
   105  end;
       
   106 
    93 
   107 local
    94 local
   108 val ss1 = comp_ss
    95 val ss1 = comp_ss
   109   addsimps simp_thms @ [@{thm "nat_number_of_def"}, @{thm "zdvd_int"}] 
    96   addsimps simp_thms @ [@{thm "nat_number_of_def"}, @{thm "zdvd_int"}] 
   110       @ map (fn r => r RS sym) 
    97       @ map (fn r => r RS sym) 
   132  addsimprocs [cancel_div_mod_proc]
   119  addsimprocs [cancel_div_mod_proc]
   133  val splits_ss = comp_ss addsimps [@{thm "mod_div_equality'"}] addsplits 
   120  val splits_ss = comp_ss addsimps [@{thm "mod_div_equality'"}] addsplits 
   134      [@{thm "split_zdiv"}, @{thm "split_zmod"}, @{thm "split_div'"}, 
   121      [@{thm "split_zdiv"}, @{thm "split_zmod"}, @{thm "split_div'"}, 
   135       @{thm "split_min"}, @{thm "split_max"}, @{thm "abs_split"}]
   122       @{thm "split_min"}, @{thm "split_max"}, @{thm "abs_split"}]
   136 in
   123 in
   137 fun nat_to_int_tac ctxt i = 
   124 fun nat_to_int_tac ctxt = 
   138   simp_tac (Simplifier.context ctxt ss1) i THEN 
   125   simp_tac (Simplifier.context ctxt ss1) THEN_ALL_NEW
   139   simp_tac (Simplifier.context ctxt ss2) i THEN 
   126   simp_tac (Simplifier.context ctxt ss2) THEN_ALL_NEW
   140   TRY (simp_tac (Simplifier.context ctxt comp_ss) i);
   127   simp_tac (Simplifier.context ctxt comp_ss);
   141 
   128 
   142 fun div_mod_tac  ctxt i = simp_tac (Simplifier.context ctxt div_mod_ss) i;
   129 fun div_mod_tac ctxt i = simp_tac (Simplifier.context ctxt div_mod_ss) i;
   143 fun splits_tac ctxt i = simp_tac (Simplifier.context ctxt splits_ss) i;
   130 fun splits_tac ctxt i = simp_tac (Simplifier.context ctxt splits_ss) i;
   144 end;
   131 end;
   145 
   132 
   146 
   133 
   147 fun eta_beta_tac ctxt i st = case try (nth (cprems_of st)) (i - 1) of
   134 fun core_cooper_tac ctxt = CSUBGOAL (fn (p, i) =>
   148    NONE => no_tac st
       
   149  | SOME p => 
       
   150    let
       
   151     val eq = (Thm.eta_long_conversion then_conv Thm.beta_conversion true) p
       
   152     val p' = Thm.rhs_of eq
       
   153     val th = implies_intr p' (equal_elim (symmetric eq) (assume p'))
       
   154    in rtac th i st
       
   155    end;
       
   156 
       
   157 
       
   158 
       
   159 fun core_cooper_tac ctxt i st = 
       
   160  case try (nth (cprems_of st)) (i - 1) of
       
   161    NONE => all_tac st
       
   162  | SOME p => 
       
   163    let 
   135    let 
   164     val cpth = 
   136     val cpth = 
   165        if !quick_and_dirty 
   137        if !quick_and_dirty 
   166        then linzqe_oracle (ProofContext.theory_of ctxt) 
   138        then linzqe_oracle (ProofContext.theory_of ctxt) 
   167              (Envir.beta_norm (Pattern.eta_long [] (term_of (Thm.dest_arg p))))
   139              (Envir.beta_norm (Pattern.eta_long [] (term_of (Thm.dest_arg p))))
   168        else arg_conv (Cooper.cooper_conv ctxt) p
   140        else arg_conv (Cooper.cooper_conv ctxt) p
   169     val p' = Thm.rhs_of cpth
   141     val p' = Thm.rhs_of cpth
   170     val th = implies_intr p' (equal_elim (symmetric cpth) (assume p'))
   142     val th = implies_intr p' (equal_elim (symmetric cpth) (assume p'))
   171    in rtac th i st end
   143    in rtac th i end
   172    handle Cooper.COOPER _ => no_tac st;
   144    handle Cooper.COOPER _ => no_tac);
   173 
   145 
   174 fun nogoal_tac i st = case try (nth (cprems_of st)) (i - 1) of
   146 fun finish_tac q = SUBGOAL (fn (_, i) =>
   175    NONE => no_tac st
   147   (if q then I else TRY) (rtac TrueI i));
   176  | SOME _ => all_tac st
       
   177 
   148 
   178 fun finish_tac q i st = case try (nth (cprems_of st)) (i - 1) of
   149 fun cooper_tac elim add_ths del_ths ctxt =
   179    NONE => all_tac st
       
   180  | SOME _ => (if q then I else TRY) (rtac TrueI i) st
       
   181 
       
   182 fun cooper_tac elim add_ths del_ths ctxt i = 
       
   183 let val ss = fst (CooperData.get ctxt) delsimps del_ths addsimps add_ths
   150 let val ss = fst (CooperData.get ctxt) delsimps del_ths addsimps add_ths
   184 in
   151 in
   185 nogoal_tac i 
   152   ObjectLogic.full_atomize_tac
   186 THEN (EVERY o (map TRY))
   153   THEN_ALL_NEW eta_long_tac
   187  [ObjectLogic.full_atomize_tac i,
   154   THEN_ALL_NEW simp_tac ss
   188   eta_beta_tac ctxt i,
   155   THEN_ALL_NEW (TRY o generalize_tac (int_nat_terms ctxt))
   189   simp_tac ss  i,
   156   THEN_ALL_NEW ObjectLogic.full_atomize_tac
   190   generalize_tac ctxt (int_nat_terms ctxt) i,
   157   THEN_ALL_NEW div_mod_tac ctxt
   191   ObjectLogic.full_atomize_tac i,
   158   THEN_ALL_NEW splits_tac ctxt
   192   div_mod_tac ctxt i,
   159   THEN_ALL_NEW simp_tac ss
   193   splits_tac ctxt i,
   160   THEN_ALL_NEW eta_long_tac
   194   simp_tac ss i,
   161   THEN_ALL_NEW nat_to_int_tac ctxt
   195   eta_beta_tac ctxt i,
   162   THEN_ALL_NEW (TRY o thin_prems_tac (is_relevant ctxt))
   196   nat_to_int_tac ctxt i, 
   163   THEN_ALL_NEW core_cooper_tac ctxt
   197   thin_prems_tac (is_relevant ctxt) i]
   164   THEN_ALL_NEW finish_tac elim
   198 THEN core_cooper_tac ctxt i THEN finish_tac elim i
       
   199 end;
   165 end;
   200 
   166 
   201 end;
   167 end;