src/HOL/Tools/Groebner_Basis/groebner.ML
changeset 23557 3fe7aea46633
parent 23514 25e69e56355d
child 23579 1a8ca0e480cd
equal deleted inserted replaced
23556:c09cc406460b 23557:3fe7aea46633
    15     val algebra_tac: thm list -> thm list -> Proof.context -> int -> tactic
    15     val algebra_tac: thm list -> thm list -> Proof.context -> int -> tactic
    16 end
    16 end
    17 
    17 
    18 structure Groebner: GROEBNER =
    18 structure Groebner: GROEBNER =
    19 struct
    19 struct
    20 open Normalizer;
    20 
    21 open Misc;
    21 open Conv Misc Normalizer;
    22 
    22 
    23 fun assocd x al d = case AList.lookup (op =) al x of SOME y => y | NONE => d;
       
    24 val rat_0 = Rat.zero;
    23 val rat_0 = Rat.zero;
    25 val rat_1 = Rat.one;
    24 val rat_1 = Rat.one;
    26 val minus_rat = Rat.neg;
    25 val minus_rat = Rat.neg;
    27 val denominator_rat = Rat.quotient_of_rat #> snd #> Rat.rat_of_int;
    26 val denominator_rat = Rat.quotient_of_rat #> snd #> Rat.rat_of_int;
    28 fun int_of_rat a =
    27 fun int_of_rat a =
   329 (* Turn proof into a certificate as sum of multipliers.                      *)
   328 (* Turn proof into a certificate as sum of multipliers.                      *)
   330 (*                                                                           *)
   329 (*                                                                           *)
   331 (* In principle this is very inefficient: in a heavily shared proof it may   *)
   330 (* In principle this is very inefficient: in a heavily shared proof it may   *)
   332 (* make the same calculation many times. Could put in a cache or something.  *)
   331 (* make the same calculation many times. Could put in a cache or something.  *)
   333 (* ------------------------------------------------------------------------- *)
   332 (* ------------------------------------------------------------------------- *)
   334 fun assoc x l = snd(find (fn p => fst p = x) l);
       
   335 
       
   336 fun resolve_proof vars prf =
   333 fun resolve_proof vars prf =
   337   case prf of
   334   case prf of
   338     Start(~1) => []
   335     Start(~1) => []
   339   | Start m => [(m,[(rat_1,map (K 0) vars)])]
   336   | Start m => [(m,[(rat_1,map (K 0) vars)])]
   340   | Mmul(pol,lin) =>
   337   | Mmul(pol,lin) =>
   343   | Add(lin1,lin2) =>
   340   | Add(lin1,lin2) =>
   344         let val lis1 = resolve_proof vars lin1
   341         let val lis1 = resolve_proof vars lin1
   345             val lis2 = resolve_proof vars lin2
   342             val lis2 = resolve_proof vars lin2
   346             val dom = distinct (op =) ((map fst lis1) union (map fst lis2))
   343             val dom = distinct (op =) ((map fst lis1) union (map fst lis2))
   347         in
   344         in
   348             map (fn n => let val a = ((assoc n lis1) handle _ => [])  (* FIXME *)
   345             map (fn n => let val a = these (AList.lookup (op =) lis1 n)
   349                              val b = ((assoc n lis2) handle _ => []) in  (* FIXME *)
   346                              val b = these (AList.lookup (op =) lis2 n)
   350                              (n,grob_add a b) end) dom end;
   347                          in (n,grob_add a b) end) dom end;
   351 
   348 
   352 (* ------------------------------------------------------------------------- *)
   349 (* ------------------------------------------------------------------------- *)
   353 (* Run the procedure and produce Weak Nullstellensatz certificate.           *)
   350 (* Run the procedure and produce Weak Nullstellensatz certificate.           *)
   354 (* ------------------------------------------------------------------------- *)
   351 (* ------------------------------------------------------------------------- *)
   355 fun grobner_weak vars pols =
   352 fun grobner_weak vars pols =
   386         fun transform_polynomial q = fold_rev (grob_add o transform_monomial) q []
   383         fun transform_polynomial q = fold_rev (grob_add o transform_monomial) q []
   387         val cert' = map (fn (c,q) => (c-1,transform_polynomial q))
   384         val cert' = map (fn (c,q) => (c-1,transform_polynomial q))
   388                         (filter (fn (k,_) => k <> 0) cert) in
   385                         (filter (fn (k,_) => k <> 0) cert) in
   389         (d,l,cert') end;
   386         (d,l,cert') end;
   390 
   387 
   391 fun string_of_pol vars pol =
       
   392     foldl (fn ((c,m),s) => ((Rat.string_of_rat c)
       
   393                             ^ "*(" ^
       
   394                             (snd (foldl
       
   395                                       (fn (e,(i,s)) =>
       
   396                                           (i+ 1,
       
   397                                            (nth vars i
       
   398                                                      |>cterm_of (the_context())  (* FIXME *)
       
   399                                                      |> string_of_cterm)^ "^"
       
   400                                            ^ (Int.toString e) ^" * " ^ s)) (0,"0") m))
       
   401                             ^ ") + ") ^ s) "" pol;
       
   402 
       
   403 
   388 
   404 (* ------------------------------------------------------------------------- *)
   389 (* ------------------------------------------------------------------------- *)
   405 (* Overall parametrized universal procedure for (semi)rings.                 *)
   390 (* Overall parametrized universal procedure for (semi)rings.                 *)
   406 (* We return an ideal_conv and the actual ring prover.                       *)
   391 (* We return an ideal_conv and the actual ring prover.                       *)
   407 (* ------------------------------------------------------------------------- *)
   392 (* ------------------------------------------------------------------------- *)
   455 
   440 
   456 val mk_object_eq = fn th => th COMP meta_eq_to_obj_eq;
   441 val mk_object_eq = fn th => th COMP meta_eq_to_obj_eq;
   457 val bool_simps = @{thms "bool_simps"};
   442 val bool_simps = @{thms "bool_simps"};
   458 val nnf_simps = @{thms "nnf_simps"};
   443 val nnf_simps = @{thms "nnf_simps"};
   459 val nnf_conv = Simplifier.rewrite (HOL_basic_ss addsimps bool_simps addsimps nnf_simps)
   444 val nnf_conv = Simplifier.rewrite (HOL_basic_ss addsimps bool_simps addsimps nnf_simps)
   460 val weak_dnf_conv = Simplifier.rewrite (HOL_basic_ss addsimps (@{thms "weak_dnf_simps"}));
   445 val weak_dnf_conv = Simplifier.rewrite (HOL_basic_ss addsimps @{thms "weak_dnf_simps"});
   461 val initial_conv =
   446 val initial_conv =
   462     Simplifier.rewrite
   447     Simplifier.rewrite
   463      (HOL_basic_ss addsimps nnf_simps
   448      (HOL_basic_ss addsimps nnf_simps
   464      addsimps [not_all, not_ex] addsimps map (fn th => th RS sym) (ex_simps @ all_simps));
   449      addsimps [not_all, not_ex] addsimps map (fn th => th RS sym) (ex_simps @ all_simps));
   465 
   450 
   466 val specl = fold_rev (fn x => fn th => instantiate' [] [SOME x] (th RS spec));
   451 val specl = fold_rev (fn x => fn th => instantiate' [] [SOME x] (th RS spec));
   467 
   452 
   468 val cTrp = @{cterm "Trueprop"};
   453 val cTrp = @{cterm "Trueprop"};
   469 val cConj = @{cterm "op &"};
   454 val cConj = @{cterm "op &"};
   470 val (cNot,false_tm) = (@{cterm "Not"}, @{cterm "False"});
   455 val (cNot,false_tm) = (@{cterm "Not"}, @{cterm "False"});
   471 val ASSUME = mk_comb cTrp #> assume;
   456 val assume_Trueprop = mk_comb cTrp #> assume;
   472 val list_mk_conj = list_mk_binop cConj;
   457 val list_mk_conj = list_mk_binop cConj;
   473 val conjs = list_dest_binop cConj;
   458 val conjs = list_dest_binop cConj;
   474 val mk_neg = mk_comb cNot;
   459 val mk_neg = mk_comb cNot;
   475 
   460 
   476 
   461 
   605 val neq_01 = prove_nz (rat_1);
   590 val neq_01 = prove_nz (rat_1);
   606 fun neq_rule n th = [prove_nz n, th] MRS neq_thm;
   591 fun neq_rule n th = [prove_nz n, th] MRS neq_thm;
   607 fun mk_add th1 = combination(Drule.arg_cong_rule ring_add_tm th1);
   592 fun mk_add th1 = combination(Drule.arg_cong_rule ring_add_tm th1);
   608 
   593 
   609 fun refute tm =
   594 fun refute tm =
   610  if tm aconvc false_tm then ASSUME tm else
   595  if tm aconvc false_tm then assume_Trueprop tm else
   611   let
   596   let
   612    val (nths0,eths0) = List.partition (is_neg o concl) (conjuncts(ASSUME tm))
   597    val (nths0,eths0) = List.partition (is_neg o concl) (HOLogic.conj_elims (assume_Trueprop tm))
   613    val  nths = filter (is_eq o Thm.dest_arg o concl) nths0
   598    val  nths = filter (is_eq o Thm.dest_arg o concl) nths0
   614    val eths = filter (is_eq o concl) eths0
   599    val eths = filter (is_eq o concl) eths0
   615   in
   600   in
   616    if null eths then
   601    if null eths then
   617     let
   602     let
   618       val th1 = end_itlist (fn th1 => fn th2 => idom_rule(conji th1 th2)) nths
   603       val th1 = end_itlist (fn th1 => fn th2 => idom_rule(HOLogic.conj_intr th1 th2)) nths
   619       val th2 = Conv.fconv_rule
   604       val th2 = Conv.fconv_rule
   620                 ((arg_conv #> arg_conv)
   605                 ((arg_conv #> arg_conv)
   621                      (binop_conv ring_normalize_conv)) th1
   606                      (binop_conv ring_normalize_conv)) th1
   622       val conc = th2 |> concl |> Thm.dest_arg
   607       val conc = th2 |> concl |> Thm.dest_arg
   623       val (l,r) = conc |> dest_eq
   608       val (l,r) = conc |> dest_eq
   633           val (l,cert) = grobner_weak vars pols
   618           val (l,cert) = grobner_weak vars pols
   634       in (vars,l,cert,neq_01)
   619       in (vars,l,cert,neq_01)
   635       end
   620       end
   636      else
   621      else
   637       let
   622       let
   638        val nth = end_itlist (fn th1 => fn th2 => idom_rule(conji th1 th2)) nths
   623        val nth = end_itlist (fn th1 => fn th2 => idom_rule(HOLogic.conj_intr th1 th2)) nths
   639        val (vars,pol::pols) =
   624        val (vars,pol::pols) =
   640           grobify_equations(list_mk_conj(Thm.dest_arg(concl nth)::map concl eths))
   625           grobify_equations(list_mk_conj(Thm.dest_arg(concl nth)::map concl eths))
   641        val (deg,l,cert) = grobner_strong vars pols pol
   626        val (deg,l,cert) = grobner_strong vars pols pol
   642        val th1 = Conv.fconv_rule((arg_conv o arg_conv)(binop_conv ring_normalize_conv)) nth
   627        val th1 = Conv.fconv_rule((arg_conv o arg_conv)(binop_conv ring_normalize_conv)) nth
   643        val th2 = funpow (Integer.machine_int deg) (idom_rule o conji th1) neq_01
   628        val th2 = funpow (Integer.machine_int deg) (idom_rule o HOLogic.conj_intr th1) neq_01
   644       in (vars,l,cert,th2)
   629       in (vars,l,cert,th2)
   645       end)
   630       end)
   646 (*    val _ = writeln ("Translating certificate to HOL inferences") *)
   631 (*    val _ = writeln ("Translating certificate to HOL inferences") *)
   647     val cert_pos = map (fn (i,p) => (i,filter (fn (c,m) => c >/ rat_0) p)) cert
   632     val cert_pos = map (fn (i,p) => (i,filter (fn (c,m) => c >/ rat_0) p)) cert
   648     val cert_neg = map (fn (i,p) => (i,map (fn (c,m) => (minus_rat c,m))
   633     val cert_neg = map (fn (i,p) => (i,map (fn (c,m) => (minus_rat c,m))
   654         end_itlist mk_add
   639         end_itlist mk_add
   655             (map (fn (i,p) => Drule.arg_cong_rule (mk_comb ring_mul_tm p)
   640             (map (fn (i,p) => Drule.arg_cong_rule (mk_comb ring_mul_tm p)
   656               (nth eths (Integer.machine_int i) |> mk_meta_eq)) pols)
   641               (nth eths (Integer.machine_int i) |> mk_meta_eq)) pols)
   657     val th1 = thm_fn herts_pos
   642     val th1 = thm_fn herts_pos
   658     val th2 = thm_fn herts_neg
   643     val th2 = thm_fn herts_neg
   659     val th3 = conji(mk_add (symmetric th1) th2 |> mk_object_eq) noteqth
   644     val th3 = HOLogic.conj_intr(mk_add (symmetric th1) th2 |> mk_object_eq) noteqth
   660     val th4 = Conv.fconv_rule ((arg_conv o arg_conv o binop_conv) ring_normalize_conv)
   645     val th4 = Conv.fconv_rule ((arg_conv o arg_conv o binop_conv) ring_normalize_conv)
   661                                (neq_rule l th3)
   646                                (neq_rule l th3)
   662     val (l,r) = dest_eq(Thm.dest_arg(concl th4))
   647     val (l,r) = dest_eq(Thm.dest_arg(concl th4))
   663    in implies_intr (mk_comb cTrp tm)
   648    in implies_intr (mk_comb cTrp tm)
   664                         (equal_elim (Drule.arg_cong_rule cTrp (eqF_intr th4))
   649                         (equal_elim (Drule.arg_cong_rule cTrp (eqF_intr th4))
   694   val rawvars = fold_rev grobvars (tm::tms) []
   679   val rawvars = fold_rev grobvars (tm::tms) []
   695   val vars = sort ord (distinct (fn (x,y) => (term_of x) aconv (term_of y)) rawvars)
   680   val vars = sort ord (distinct (fn (x,y) => (term_of x) aconv (term_of y)) rawvars)
   696   val pols = map (grobify_term vars) tms
   681   val pols = map (grobify_term vars) tms
   697   val pol = grobify_term vars tm
   682   val pol = grobify_term vars tm
   698   val cert = grobner_ideal vars pols pol
   683   val cert = grobner_ideal vars pols pol
   699  in map (fn n => let val p = assocd n cert [] in holify_polynomial vars p end)
   684  in map (fn n => these (AList.lookup (op =) cert n) |> holify_polynomial vars)
   700         (map Integer.int (0 upto (length pols - 1)))
   685         (map Integer.int (0 upto (length pols - 1)))
   701  end
   686  end
   702 in (ring,ideal)
   687 in (ring,ideal)
   703 end;
   688 end;
   704 
   689 
   731       | SOME (res as (theory, {is_const, dest_const, mk_const, conv = ring_eq_conv})) =>
   716       | SOME (res as (theory, {is_const, dest_const, mk_const, conv = ring_eq_conv})) =>
   732         fst (ring_and_ideal_conv theory
   717         fst (ring_and_ideal_conv theory
   733           dest_const (mk_const (Thm.ctyp_of_term tm)) (ring_eq_conv ctxt)
   718           dest_const (mk_const (Thm.ctyp_of_term tm)) (ring_eq_conv ctxt)
   734           (semiring_normalize_wrapper ctxt res)) form));
   719           (semiring_normalize_wrapper ctxt res)) form));
   735 
   720 
   736 fun algebra_tac add_ths del_ths ctxt i = ObjectLogic.full_atomize_tac i 
   721 fun algebra_tac add_ths del_ths ctxt i = ObjectLogic.full_atomize_tac i
   737   THEN (simp_tac (fst (NormalizerData.get ctxt) delsimps del_ths addsimps add_ths) i)
   722   THEN (simp_tac (fst (NormalizerData.get ctxt) delsimps del_ths addsimps add_ths) i)
   738   THEN (fn st =>
   723   THEN (fn st =>
   739    case try (nth (cprems_of st)) (i - 1) of
   724    case try (nth (cprems_of st)) (i - 1) of
   740     NONE => no_tac st
   725     NONE => no_tac st
   741   | SOME p => let val th = ring_conv ctxt (Thm.dest_arg p)
   726   | SOME p => let val th = ring_conv ctxt (Thm.dest_arg p)
   742               in rtac th i st end
   727               in rtac th i st end
   743               handle TERM _ => no_tac st
   728               handle TERM _ => no_tac st
   744                    | THM _ => no_tac st
   729                    | THM _ => no_tac st
   745                    | ERROR _ => no_tac st
   730                    | ERROR _ => no_tac st    (* FIXME !? *)
   746                    | CTERM _ => no_tac st);
   731                    | CTERM _ => no_tac st);
   747 
   732 
   748 end;
   733 end;