src/HOL/Library/comm_ring.ML
changeset 33356 9157d0f9f00e
parent 32149 ef59550a55d3
child 33494 2b5b0f9e271c
equal deleted inserted replaced
33351:37ec56ac3fd4 33356:9157d0f9f00e
     1 (*  Author:     Amine Chaieb
       
     2 
       
     3 Tactic for solving equalities over commutative rings.
       
     4 *)
       
     5 
       
     6 signature COMM_RING =
       
     7 sig
       
     8   val comm_ring_tac : Proof.context -> int -> tactic
       
     9   val setup : theory -> theory
       
    10 end
       
    11 
       
    12 structure CommRing: COMM_RING =
       
    13 struct
       
    14 
       
    15 (* The Cring exception for erronous uses of cring_tac *)
       
    16 exception CRing of string;
       
    17 
       
    18 (* Zero and One of the commutative ring *)
       
    19 fun cring_zero T = Const (@{const_name HOL.zero}, T);
       
    20 fun cring_one T = Const (@{const_name HOL.one}, T);
       
    21 
       
    22 (* reification functions *)
       
    23 (* add two polynom expressions *)
       
    24 fun polT t = Type ("Commutative_Ring.pol", [t]);
       
    25 fun polexT t = Type ("Commutative_Ring.polex", [t]);
       
    26 
       
    27 (* pol *)
       
    28 fun pol_Pc t = Const ("Commutative_Ring.pol.Pc", t --> polT t);
       
    29 fun pol_Pinj t = Const ("Commutative_Ring.pol.Pinj", HOLogic.natT --> polT t --> polT t);
       
    30 fun pol_PX t = Const ("Commutative_Ring.pol.PX", polT t --> HOLogic.natT --> polT t --> polT t);
       
    31 
       
    32 (* polex *)
       
    33 fun polex_add t = Const ("Commutative_Ring.polex.Add", polexT t --> polexT t --> polexT t);
       
    34 fun polex_sub t = Const ("Commutative_Ring.polex.Sub", polexT t --> polexT t --> polexT t);
       
    35 fun polex_mul t = Const ("Commutative_Ring.polex.Mul", polexT t --> polexT t --> polexT t);
       
    36 fun polex_neg t = Const ("Commutative_Ring.polex.Neg", polexT t --> polexT t);
       
    37 fun polex_pol t = Const ("Commutative_Ring.polex.Pol", polT t --> polexT t);
       
    38 fun polex_pow t = Const ("Commutative_Ring.polex.Pow", polexT t --> HOLogic.natT --> polexT t);
       
    39 
       
    40 (* reification of polynoms : primitive cring expressions *)
       
    41 fun reif_pol T vs (t as Free _) =
       
    42       let
       
    43         val one = @{term "1::nat"};
       
    44         val i = find_index (fn t' => t' = t) vs
       
    45       in if i = 0
       
    46         then pol_PX T $ (pol_Pc T $ cring_one T)
       
    47           $ one $ (pol_Pc T $ cring_zero T)
       
    48         else pol_Pinj T $ HOLogic.mk_nat i
       
    49           $ (pol_PX T $ (pol_Pc T $ cring_one T)
       
    50             $ one $ (pol_Pc T $ cring_zero T))
       
    51         end
       
    52   | reif_pol T vs t = pol_Pc T $ t;
       
    53 
       
    54 (* reification of polynom expressions *)
       
    55 fun reif_polex T vs (Const (@{const_name HOL.plus}, _) $ a $ b) =
       
    56       polex_add T $ reif_polex T vs a $ reif_polex T vs b
       
    57   | reif_polex T vs (Const (@{const_name HOL.minus}, _) $ a $ b) =
       
    58       polex_sub T $ reif_polex T vs a $ reif_polex T vs b
       
    59   | reif_polex T vs (Const (@{const_name HOL.times}, _) $ a $ b) =
       
    60       polex_mul T $ reif_polex T vs a $ reif_polex T vs b
       
    61   | reif_polex T vs (Const (@{const_name HOL.uminus}, _) $ a) =
       
    62       polex_neg T $ reif_polex T vs a
       
    63   | reif_polex T vs (Const (@{const_name Power.power}, _) $ a $ n) =
       
    64       polex_pow T $ reif_polex T vs a $ n
       
    65   | reif_polex T vs t = polex_pol T $ reif_pol T vs t;
       
    66 
       
    67 (* reification of the equation *)
       
    68 val cr_sort = @{sort "comm_ring_1"};
       
    69 
       
    70 fun reif_eq thy (eq as Const("op =", Type("fun", [T, _])) $ lhs $ rhs) =
       
    71       if Sign.of_sort thy (T, cr_sort) then
       
    72         let
       
    73           val fs = OldTerm.term_frees eq;
       
    74           val cvs = cterm_of thy (HOLogic.mk_list T fs);
       
    75           val clhs = cterm_of thy (reif_polex T fs lhs);
       
    76           val crhs = cterm_of thy (reif_polex T fs rhs);
       
    77           val ca = ctyp_of thy T;
       
    78         in (ca, cvs, clhs, crhs) end
       
    79       else raise CRing ("reif_eq: not an equation over " ^ Syntax.string_of_sort_global thy cr_sort)
       
    80   | reif_eq _ _ = raise CRing "reif_eq: not an equation";
       
    81 
       
    82 (* The cring tactic *)
       
    83 (* Attention: You have to make sure that no t^0 is in the goal!! *)
       
    84 (* Use simply rewriting t^0 = 1 *)
       
    85 val cring_simps =
       
    86   [@{thm mkPX_def}, @{thm mkPinj_def}, @{thm sub_def}, @{thm power_add},
       
    87     @{thm even_def}, @{thm pow_if}, sym OF [@{thm power_add}]];
       
    88 
       
    89 fun comm_ring_tac ctxt = SUBGOAL (fn (g, i) =>
       
    90   let
       
    91     val thy = ProofContext.theory_of ctxt;
       
    92     val cring_ss = Simplifier.simpset_of ctxt  (*FIXME really the full simpset!?*)
       
    93       addsimps cring_simps;
       
    94     val (ca, cvs, clhs, crhs) = reif_eq thy (HOLogic.dest_Trueprop g)
       
    95     val norm_eq_th =
       
    96       simplify cring_ss (instantiate' [SOME ca] [SOME clhs, SOME crhs, SOME cvs] @{thm norm_eq})
       
    97   in
       
    98     cut_rules_tac [norm_eq_th] i
       
    99     THEN (simp_tac cring_ss i)
       
   100     THEN (simp_tac cring_ss i)
       
   101   end);
       
   102 
       
   103 val setup =
       
   104   Method.setup @{binding comm_ring} (Scan.succeed (SIMPLE_METHOD' o comm_ring_tac))
       
   105     "reflective decision procedure for equalities over commutative rings" #>
       
   106   Method.setup @{binding algebra} (Scan.succeed (SIMPLE_METHOD' o comm_ring_tac))
       
   107     "method for proving algebraic properties (same as comm_ring)";
       
   108 
       
   109 end;