src/HOL/Tools/Qelim/cooper.ML
changeset 36806 fc27b0465a4c
parent 36805 929b23461a14
child 36807 abcfc8372694
equal deleted inserted replaced
36805:929b23461a14 36806:fc27b0465a4c
    11   val del: term list -> attribute
    11   val del: term list -> attribute
    12   val add: term list -> attribute 
    12   val add: term list -> attribute 
    13   val conv: Proof.context -> conv
    13   val conv: Proof.context -> conv
    14   val tac: bool -> thm list -> thm list -> Proof.context -> int -> tactic
    14   val tac: bool -> thm list -> thm list -> Proof.context -> int -> tactic
    15   val method: (Proof.context -> Method.method) context_parser
    15   val method: (Proof.context -> Method.method) context_parser
    16   exception COOPER of string * exn
       
    17   val setup: theory -> theory
    16   val setup: theory -> theory
    18 end;
    17 end;
    19 
    18 
    20 structure Cooper: COOPER =
    19 structure Cooper: COOPER =
    21 struct
    20 struct
   250  | (_, _) => numeral2 Integer.add tm1 tm2;
   249  | (_, _) => numeral2 Integer.add tm1 tm2;
   251 
   250 
   252 fun linear_neg tm = linear_cmul ~1 tm;
   251 fun linear_neg tm = linear_cmul ~1 tm;
   253 fun linear_sub vars tm1 tm2 = linear_add vars tm1 (linear_neg tm2);
   252 fun linear_sub vars tm1 tm2 = linear_add vars tm1 (linear_neg tm2);
   254 
   253 
   255 exception COOPER of string * exn;
   254 exception COOPER of string;
   256 
       
   257 fun cooper s = raise COOPER ("Cooper failed", ERROR s);
       
   258 
   255 
   259 fun lint vars tm =  if is_numeral tm then tm  else case tm of
   256 fun lint vars tm =  if is_numeral tm then tm  else case tm of
   260   Const (@{const_name Groups.uminus}, _) $ t => linear_neg (lint vars t)
   257   Const (@{const_name Groups.uminus}, _) $ t => linear_neg (lint vars t)
   261 | Const (@{const_name Groups.plus}, _) $ s $ t => linear_add vars (lint vars s) (lint vars t)
   258 | Const (@{const_name Groups.plus}, _) $ s $ t => linear_add vars (lint vars s) (lint vars t)
   262 | Const (@{const_name Groups.minus}, _) $ s $ t => linear_sub vars (lint vars s) (lint vars t)
   259 | Const (@{const_name Groups.minus}, _) $ s $ t => linear_sub vars (lint vars s) (lint vars t)
   263 | Const (@{const_name Groups.times}, _) $ s $ t =>
   260 | Const (@{const_name Groups.times}, _) $ s $ t =>
   264   let val s' = lint vars s
   261   let val s' = lint vars s
   265       val t' = lint vars t
   262       val t' = lint vars t
   266   in if is_numeral s' then (linear_cmul (dest_numeral s') t')
   263   in if is_numeral s' then (linear_cmul (dest_numeral s') t')
   267      else if is_numeral t' then (linear_cmul (dest_numeral t') s')
   264      else if is_numeral t' then (linear_cmul (dest_numeral t') s')
   268      else raise COOPER ("Cooper Failed", TERM ("lint: not linear",[tm]))
   265      else raise COOPER "lint: not linear"
   269   end
   266   end
   270  | _ => addC $ (mulC $ one $ tm) $ zero;
   267  | _ => addC $ (mulC $ one $ tm) $ zero;
   271 
   268 
   272 fun lin (vs as x::_) (Const (@{const_name Not}, _) $ (Const (@{const_name Orderings.less}, T) $ s $ t)) =
   269 fun lin (vs as x::_) (Const (@{const_name Not}, _) $ (Const (@{const_name Orderings.less}, T) $ s $ t)) =
   273     lin vs (Const (@{const_name Orderings.less_eq}, T) $ t $ s)
   270     lin vs (Const (@{const_name Orderings.less_eq}, T) $ t $ s)
   567   in
   564   in
   568    Qelim.gen_qelim_conv pcv postcv pcv (cons o term_of)
   565    Qelim.gen_qelim_conv pcv postcv pcv (cons o term_of)
   569       (OldTerm.term_frees (term_of p)) (linearize_conv ctxt) (integer_nnf_conv ctxt)
   566       (OldTerm.term_frees (term_of p)) (linearize_conv ctxt) (integer_nnf_conv ctxt)
   570       (cooperex_conv ctxt) p
   567       (cooperex_conv ctxt) p
   571   end
   568   end
   572   handle  CTERM s => raise COOPER ("Cooper Failed", CTERM s)
   569   handle  CTERM s => raise COOPER "bad cterm"
   573         | THM s => raise COOPER ("Cooper Failed", THM s)
   570         | THM s => raise COOPER "bad thm"
   574         | TYPE s => raise COOPER ("Cooper Failed", TYPE s)
   571         | TYPE s => raise COOPER "bad type"
   575 in val conv = conv
   572 in val conv = conv
   576 end;
   573 end;
   577 
   574 
   578 fun i_of_term vs t = case t
   575 fun i_of_term vs t = case t
   579  of Free (xn, xT) => (case AList.lookup (op aconv) vs t
   576  of Free (xn, xT) => (case AList.lookup (op aconv) vs t
   580      of NONE   => cooper "Variable not found in the list!"
   577      of NONE   => raise COOPER "reification: variable not found in list"
   581       | SOME n => Cooper_Procedure.Bound n)
   578       | SOME n => Cooper_Procedure.Bound n)
   582   | @{term "0::int"} => Cooper_Procedure.C 0
   579   | @{term "0::int"} => Cooper_Procedure.C 0
   583   | @{term "1::int"} => Cooper_Procedure.C 1
   580   | @{term "1::int"} => Cooper_Procedure.C 1
   584   | Term.Bound i => Cooper_Procedure.Bound i
   581   | Term.Bound i => Cooper_Procedure.Bound i
   585   | Const(@{const_name Groups.uminus},_)$t' => Cooper_Procedure.Neg (i_of_term vs t')
   582   | Const(@{const_name Groups.uminus},_)$t' => Cooper_Procedure.Neg (i_of_term vs t')
   587   | Const(@{const_name Groups.minus},_)$t1$t2 => Cooper_Procedure.Sub (i_of_term vs t1,i_of_term vs t2)
   584   | Const(@{const_name Groups.minus},_)$t1$t2 => Cooper_Procedure.Sub (i_of_term vs t1,i_of_term vs t2)
   588   | Const(@{const_name Groups.times},_)$t1$t2 =>
   585   | Const(@{const_name Groups.times},_)$t1$t2 =>
   589      (Cooper_Procedure.Mul (HOLogic.dest_number t1 |> snd, i_of_term vs t2)
   586      (Cooper_Procedure.Mul (HOLogic.dest_number t1 |> snd, i_of_term vs t2)
   590     handle TERM _ =>
   587     handle TERM _ =>
   591        (Cooper_Procedure.Mul (HOLogic.dest_number t2 |> snd, i_of_term vs t1)
   588        (Cooper_Procedure.Mul (HOLogic.dest_number t2 |> snd, i_of_term vs t1)
   592         handle TERM _ => cooper "Reification: Unsupported kind of multiplication"))
   589         handle TERM _ => raise COOPER "reification: unsupported kind of multiplication"))
   593   | _ => (Cooper_Procedure.C (HOLogic.dest_number t |> snd)
   590   | _ => (Cooper_Procedure.C (HOLogic.dest_number t |> snd)
   594            handle TERM _ => cooper "Reification: unknown term");
   591            handle TERM _ => raise COOPER "reification: unknown term");
   595 
   592 
   596 fun qf_of_term ps vs t =  case t
   593 fun qf_of_term ps vs t =  case t
   597  of Const("True",_) => Cooper_Procedure.T
   594  of Const("True",_) => Cooper_Procedure.T
   598   | Const("False",_) => Cooper_Procedure.F
   595   | Const("False",_) => Cooper_Procedure.F
   599   | Const(@{const_name Orderings.less},_)$t1$t2 => Cooper_Procedure.Lt (Cooper_Procedure.Sub (i_of_term vs t1,i_of_term vs t2))
   596   | Const(@{const_name Orderings.less},_)$t1$t2 => Cooper_Procedure.Lt (Cooper_Procedure.Sub (i_of_term vs t1,i_of_term vs t2))
   600   | Const(@{const_name Orderings.less_eq},_)$t1$t2 => Cooper_Procedure.Le (Cooper_Procedure.Sub(i_of_term vs t1,i_of_term vs t2))
   597   | Const(@{const_name Orderings.less_eq},_)$t1$t2 => Cooper_Procedure.Le (Cooper_Procedure.Sub(i_of_term vs t1,i_of_term vs t2))
   601   | Const(@{const_name Rings.dvd},_)$t1$t2 =>
   598   | Const(@{const_name Rings.dvd},_)$t1$t2 =>
   602       (Cooper_Procedure.Dvd (HOLogic.dest_number t1 |> snd, i_of_term vs t2) handle TERM _ => cooper "Reification: unsupported dvd")
   599       (Cooper_Procedure.Dvd (HOLogic.dest_number t1 |> snd, i_of_term vs t2)
       
   600         handle TERM _ => raise COOPER "reification: unsupported dvd")
   603   | @{term "op = :: int => _"}$t1$t2 => Cooper_Procedure.Eq (Cooper_Procedure.Sub (i_of_term vs t1,i_of_term vs t2))
   601   | @{term "op = :: int => _"}$t1$t2 => Cooper_Procedure.Eq (Cooper_Procedure.Sub (i_of_term vs t1,i_of_term vs t2))
   604   | @{term "op = :: bool => _ "}$t1$t2 => Cooper_Procedure.Iff(qf_of_term ps vs t1,qf_of_term ps vs t2)
   602   | @{term "op = :: bool => _ "}$t1$t2 => Cooper_Procedure.Iff(qf_of_term ps vs t1,qf_of_term ps vs t2)
   605   | Const("op &",_)$t1$t2 => Cooper_Procedure.And(qf_of_term ps vs t1,qf_of_term ps vs t2)
   603   | Const("op &",_)$t1$t2 => Cooper_Procedure.And(qf_of_term ps vs t1,qf_of_term ps vs t2)
   606   | Const("op |",_)$t1$t2 => Cooper_Procedure.Or(qf_of_term ps vs t1,qf_of_term ps vs t2)
   604   | Const("op |",_)$t1$t2 => Cooper_Procedure.Or(qf_of_term ps vs t1,qf_of_term ps vs t2)
   607   | Const("op -->",_)$t1$t2 => Cooper_Procedure.Imp(qf_of_term ps vs t1,qf_of_term ps vs t2)
   605   | Const("op -->",_)$t1$t2 => Cooper_Procedure.Imp(qf_of_term ps vs t1,qf_of_term ps vs t2)
   615      let val (xn',p') = variant_abs (xn,xT,p)
   613      let val (xn',p') = variant_abs (xn,xT,p)
   616          val vs' = (Free (xn',xT), 0) :: (map (fn(v,n) => (v,1+ n)) vs)
   614          val vs' = (Free (xn',xT), 0) :: (map (fn(v,n) => (v,1+ n)) vs)
   617      in Cooper_Procedure.A (qf_of_term ps vs' p')
   615      in Cooper_Procedure.A (qf_of_term ps vs' p')
   618      end
   616      end
   619   | _ =>(case AList.lookup (op aconv) ps t of
   617   | _ =>(case AList.lookup (op aconv) ps t of
   620            NONE => cooper "Reification: unknown term!"
   618            NONE => raise COOPER "reification: unknown term"
   621          | SOME n => Cooper_Procedure.Closed n);
   619          | SOME n => Cooper_Procedure.Closed n);
   622 
   620 
   623 local
   621 local
   624  val ops = [@{term "op &"}, @{term "op |"}, @{term "op -->"}, @{term "op = :: bool => _"},
   622  val ops = [@{term "op &"}, @{term "op |"}, @{term "op -->"}, @{term "op = :: bool => _"},
   625              @{term "op = :: int => _"}, @{term "op < :: int => _"},
   623              @{term "op = :: int => _"}, @{term "op < :: int => _"},
   670  | Cooper_Procedure.And(t1,t2) => HOLogic.conj$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
   668  | Cooper_Procedure.And(t1,t2) => HOLogic.conj$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
   671  | Cooper_Procedure.Or(t1,t2) => HOLogic.disj$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
   669  | Cooper_Procedure.Or(t1,t2) => HOLogic.disj$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
   672  | Cooper_Procedure.Imp(t1,t2) => HOLogic.imp$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
   670  | Cooper_Procedure.Imp(t1,t2) => HOLogic.imp$(term_of_qf ps vs t1)$(term_of_qf ps vs t2)
   673  | Cooper_Procedure.Iff(t1,t2) => @{term "op = :: bool => _"} $ term_of_qf ps vs t1 $ term_of_qf ps vs t2
   671  | Cooper_Procedure.Iff(t1,t2) => @{term "op = :: bool => _"} $ term_of_qf ps vs t1 $ term_of_qf ps vs t2
   674  | Cooper_Procedure.Closed n => the (myassoc2 ps n)
   672  | Cooper_Procedure.Closed n => the (myassoc2 ps n)
   675  | Cooper_Procedure.NClosed n => term_of_qf ps vs (Cooper_Procedure.Not (Cooper_Procedure.Closed n))
   673  | Cooper_Procedure.NClosed n => term_of_qf ps vs (Cooper_Procedure.Not (Cooper_Procedure.Closed n));
   676  | _ => cooper "If this is raised, Isabelle/HOL or code generator is inconsistent!";
       
   677 
   674 
   678 fun invoke t =
   675 fun invoke t =
   679   let
   676   let
   680     val (vs, ps) = pairself (map_index swap) (OldTerm.term_frees t, term_bools [] t);
   677     val (vs, ps) = pairself (map_index swap) (OldTerm.term_frees t, term_bools [] t);
   681   in
   678   in