src/HOL/Decision_Procs/Parametric_Ferrante_Rackoff.thy
changeset 35045 a77d200e6503
parent 35033 e47934673b74
child 35084 e25eedfc15ce
equal deleted inserted replaced
35044:7c761a4bd91f 35045:a77d200e6503
     5 header{* A formalization of Ferrante and Rackoff's procedure with polynomial parameters, see Paper in CALCULEMUS 2008 *}
     5 header{* A formalization of Ferrante and Rackoff's procedure with polynomial parameters, see Paper in CALCULEMUS 2008 *}
     6 
     6 
     7 theory Parametric_Ferrante_Rackoff
     7 theory Parametric_Ferrante_Rackoff
     8 imports Reflected_Multivariate_Polynomial 
     8 imports Reflected_Multivariate_Polynomial 
     9   "~~/src/HOL/Decision_Procs/Dense_Linear_Order"
     9   "~~/src/HOL/Decision_Procs/Dense_Linear_Order"
       
    10   Efficient_Nat
    10 begin
    11 begin
    11 
       
    12 
    12 
    13 subsection {* Terms *}
    13 subsection {* Terms *}
    14 
    14 
    15 datatype tm = CP poly | Bound nat | Add tm tm | Mul poly tm 
    15 datatype tm = CP poly | Bound nat | Add tm tm | Mul poly tm 
    16   | Neg tm | Sub tm tm | CNP nat poly tm
    16   | Neg tm | Sub tm tm | CNP nat poly tm
  2592                pp' = polyadd (p,p')
  2592                pp' = polyadd (p,p')
  2593            in (if pp' = 0\<^sub>p then cc' else CN cc' n pp')))"
  2593            in (if pp' = 0\<^sub>p then cc' else CN cc' n pp')))"
  2594   by (simp add: Let_def stupid)
  2594   by (simp add: Let_def stupid)
  2595 
  2595 
  2596 
  2596 
  2597 
       
  2598 (*
       
  2599 lemmas [code func] = polysub_def
       
  2600 lemmas [code func del] = Zero_nat_def
       
  2601 code_gen  "frpar" in SML to FRParTest
       
  2602 *)
       
  2603 
       
  2604 section{* Second implemenation: Case splits not local *}
  2597 section{* Second implemenation: Case splits not local *}
  2605 
  2598 
  2606 lemma fr_eq2:  assumes lp: "islin p"
  2599 lemma fr_eq2:  assumes lp: "islin p"
  2607   shows "(\<exists> x. Ifm vs (x#bs) p) \<longleftrightarrow> 
  2600   shows "(\<exists> x. Ifm vs (x#bs) p) \<longleftrightarrow> 
  2608    ((Ifm vs (x#bs) (minusinf p)) \<or> (Ifm vs (x#bs) (plusinf p)) \<or> 
  2601    ((Ifm vs (x#bs) (minusinf p)) \<or> (Ifm vs (x#bs) (plusinf p)) \<or> 
  2943   from ferrack2 have th: "\<forall>bs p. qfree p \<longrightarrow> qfree (ferrack2 p) \<and> Ifm vs bs (ferrack2 p) = Ifm vs bs (E p)" by blast
  2936   from ferrack2 have th: "\<forall>bs p. qfree p \<longrightarrow> qfree (ferrack2 p) \<and> Ifm vs bs (ferrack2 p) = Ifm vs bs (E p)" by blast
  2944   from qelim[OF th, of "prep p" bs] 
  2937   from qelim[OF th, of "prep p" bs] 
  2945 show ?thesis  unfolding frpar2_def by (auto simp add: prep)
  2938 show ?thesis  unfolding frpar2_def by (auto simp add: prep)
  2946 qed
  2939 qed
  2947 
  2940 
  2948 code_module FRPar
  2941 ML {* 
  2949   contains 
       
  2950   frpar = "frpar"
       
  2951   frpar2 = "frpar2"
       
  2952   test = "%x . frpar (E(Lt (Mul 1\<^sub>p (Bound 0))))"
       
  2953 
       
  2954 ML{* 
       
  2955 
       
  2956 structure ReflectedFRPar = 
  2942 structure ReflectedFRPar = 
  2957 struct
  2943 struct
  2958 
  2944 
  2959 val bT = HOLogic.boolT;
  2945 val bT = HOLogic.boolT;
  2960 fun num rT x = HOLogic.mk_number rT x;
  2946 fun num rT x = HOLogic.mk_number rT x;
  2981   Const ("Suc",_)$t' => 1 + dest_nat t'
  2967   Const ("Suc",_)$t' => 1 + dest_nat t'
  2982 | _ => (snd o HOLogic.dest_number) t;
  2968 | _ => (snd o HOLogic.dest_number) t;
  2983 
  2969 
  2984 fun num_of_term m t = 
  2970 fun num_of_term m t = 
  2985  case t of
  2971  case t of
  2986    Const(@{const_name Algebras.uminus},_)$t => FRPar.Neg (num_of_term m t)
  2972    Const(@{const_name Algebras.uminus},_)$t => @{code poly.Neg} (num_of_term m t)
  2987  | Const(@{const_name Algebras.plus},_)$a$b => FRPar.Add (num_of_term m a, num_of_term m b)
  2973  | Const(@{const_name Algebras.plus},_)$a$b => @{code poly.Add} (num_of_term m a, num_of_term m b)
  2988  | Const(@{const_name Algebras.minus},_)$a$b => FRPar.Sub (num_of_term m a, num_of_term m b)
  2974  | Const(@{const_name Algebras.minus},_)$a$b => @{code poly.Sub} (num_of_term m a, num_of_term m b)
  2989  | Const(@{const_name Algebras.times},_)$a$b => FRPar.Mul (num_of_term m a, num_of_term m b)
  2975  | Const(@{const_name Algebras.times},_)$a$b => @{code poly.Mul} (num_of_term m a, num_of_term m b)
  2990  | Const(@{const_name Power.power},_)$a$n => FRPar.Pw (num_of_term m a, dest_nat n)
  2976  | Const(@{const_name Power.power},_)$a$n => @{code poly.Pw} (num_of_term m a, dest_nat n)
  2991  | Const(@{const_name Algebras.divide},_)$a$b => FRPar.C (HOLogic.dest_number a |> snd, HOLogic.dest_number b |> snd)
  2977  | Const(@{const_name Algebras.divide},_)$a$b => @{code poly.C} (HOLogic.dest_number a |> snd, HOLogic.dest_number b |> snd)
  2992  | _ => (FRPar.C (HOLogic.dest_number t |> snd,1) 
  2978  | _ => (@{code poly.C} (HOLogic.dest_number t |> snd,1) 
  2993          handle TERM _ => FRPar.Bound (AList.lookup (op aconv) m t |> the));
  2979          handle TERM _ => @{code poly.Bound} (AList.lookup (op aconv) m t |> the));
  2994 
  2980 
  2995 fun tm_of_term m m' t = 
  2981 fun tm_of_term m m' t = 
  2996  case t of
  2982  case t of
  2997    Const(@{const_name Algebras.uminus},_)$t => FRPar.tm_Neg (tm_of_term m m' t)
  2983    Const(@{const_name Algebras.uminus},_)$t => @{code Neg} (tm_of_term m m' t)
  2998  | Const(@{const_name Algebras.plus},_)$a$b => FRPar.tm_Add (tm_of_term m m' a, tm_of_term m m' b)
  2984  | Const(@{const_name Algebras.plus},_)$a$b => @{code Add} (tm_of_term m m' a, tm_of_term m m' b)
  2999  | Const(@{const_name Algebras.minus},_)$a$b => FRPar.tm_Sub (tm_of_term m m' a, tm_of_term m m' b)
  2985  | Const(@{const_name Algebras.minus},_)$a$b => @{code Sub} (tm_of_term m m' a, tm_of_term m m' b)
  3000  | Const(@{const_name Algebras.times},_)$a$b => FRPar.tm_Mul (num_of_term m' a, tm_of_term m m' b)
  2986  | Const(@{const_name Algebras.times},_)$a$b => @{code Mul} (num_of_term m' a, tm_of_term m m' b)
  3001  | _ => (FRPar.CP (num_of_term m' t) 
  2987  | _ => (@{code CP} (num_of_term m' t) 
  3002          handle TERM _ => FRPar.tm_Bound (AList.lookup (op aconv) m t |> the)
  2988          handle TERM _ => @{code Bound} (AList.lookup (op aconv) m t |> the)
  3003               | Option => FRPar.tm_Bound (AList.lookup (op aconv) m t |> the));
  2989               | Option => @{code Bound} (AList.lookup (op aconv) m t |> the));
  3004 
  2990 
  3005 fun term_of_num T m t = 
  2991 fun term_of_num T m t = 
  3006  case t of
  2992  case t of
  3007   FRPar.C (a,b) => (if b = 1 then num T a else if b=0 then (rz T) 
  2993   @{code poly.C} (a,b) => (if b = 1 then num T a else if b=0 then (rz T) 
  3008                                         else (divt T) $ num T a $ num T b)
  2994                                         else (divt T) $ num T a $ num T b)
  3009 | FRPar.Bound i => AList.lookup (op = : int*int -> bool) m i |> the
  2995 | @{code poly.Bound} i => AList.lookup (op = : int*int -> bool) m i |> the
  3010 | FRPar.Add(a,b) => (plust T)$(term_of_num T m a)$(term_of_num T m b)
  2996 | @{code poly.Add} (a,b) => (plust T)$(term_of_num T m a)$(term_of_num T m b)
  3011 | FRPar.Mul(a,b) => (timest T)$(term_of_num T m a)$(term_of_num T m b)
  2997 | @{code poly.Mul} (a,b) => (timest T)$(term_of_num T m a)$(term_of_num T m b)
  3012 | FRPar.Sub(a,b) => (minust T)$(term_of_num T m a)$(term_of_num T m b)
  2998 | @{code poly.Sub} (a,b) => (minust T)$(term_of_num T m a)$(term_of_num T m b)
  3013 | FRPar.Neg a => (uminust T)$(term_of_num T m a)
  2999 | @{code poly.Neg} a => (uminust T)$(term_of_num T m a)
  3014 | FRPar.Pw(a,n) => (powt T)$(term_of_num T m t)$(HOLogic.mk_number HOLogic.natT n)
  3000 | @{code poly.Pw} (a,n) => (powt T)$(term_of_num T m t)$(HOLogic.mk_number HOLogic.natT n)
  3015 | FRPar.CN(c,n,p) => term_of_num T m (FRPar.Add(c,FRPar.Mul(FRPar.Bound n, p)))
  3001 | @{code poly.CN} (c,n,p) => term_of_num T m (@{code poly.Add} (c, @{code poly.Mul} (@{code poly.Bound} n, p)))
  3016 | _ => error "term_of_num: Unknown term";
  3002 | _ => error "term_of_num: Unknown term";
  3017 
  3003 
  3018 fun term_of_tm T m m' t = 
  3004 fun term_of_tm T m m' t = 
  3019  case t of
  3005  case t of
  3020   FRPar.CP p => term_of_num T m' p
  3006   @{code CP} p => term_of_num T m' p
  3021 | FRPar.tm_Bound i => AList.lookup (op = : int*int -> bool) m i |> the
  3007 | @{code Bound} i => AList.lookup (op = : int*int -> bool) m i |> the
  3022 | FRPar.tm_Add(a,b) => (plust T)$(term_of_tm T m m' a)$(term_of_tm T m m' b)
  3008 | @{code Add} (a,b) => (plust T)$(term_of_tm T m m' a)$(term_of_tm T m m' b)
  3023 | FRPar.tm_Mul(a,b) => (timest T)$(term_of_num T m' a)$(term_of_tm T m m' b)
  3009 | @{code Mul} (a,b) => (timest T)$(term_of_num T m' a)$(term_of_tm T m m' b)
  3024 | FRPar.tm_Sub(a,b) => (minust T)$(term_of_tm T m m' a)$(term_of_tm T m m' b)
  3010 | @{code Sub} (a,b) => (minust T)$(term_of_tm T m m' a)$(term_of_tm T m m' b)
  3025 | FRPar.tm_Neg a => (uminust T)$(term_of_tm T m m' a)
  3011 | @{code Neg} a => (uminust T)$(term_of_tm T m m' a)
  3026 | FRPar.CNP(n,c,p) => term_of_tm T m m' (FRPar.tm_Add(FRPar.tm_Mul(c, FRPar.tm_Bound n), p))
  3012 | @{code CNP} (n,c,p) => term_of_tm T m m' (@{code Add}
       
  3013      (@{code Mul} (c, @{code Bound} n), p))
  3027 | _ => error "term_of_tm: Unknown term";
  3014 | _ => error "term_of_tm: Unknown term";
  3028 
  3015 
  3029 fun fm_of_term m m' fm = 
  3016 fun fm_of_term m m' fm = 
  3030  case fm of
  3017  case fm of
  3031     Const("True",_) => FRPar.T
  3018     Const("True",_) => @{code T}
  3032   | Const("False",_) => FRPar.F
  3019   | Const("False",_) => @{code F}
  3033   | Const("Not",_)$p => FRPar.NOT (fm_of_term m m' p)
  3020   | Const("Not",_)$p => @{code NOT} (fm_of_term m m' p)
  3034   | Const("op &",_)$p$q => FRPar.And(fm_of_term m m' p, fm_of_term m m' q)
  3021   | Const("op &",_)$p$q => @{code And} (fm_of_term m m' p, fm_of_term m m' q)
  3035   | Const("op |",_)$p$q => FRPar.Or(fm_of_term m m' p, fm_of_term m m' q)
  3022   | Const("op |",_)$p$q => @{code Or} (fm_of_term m m' p, fm_of_term m m' q)
  3036   | Const("op -->",_)$p$q => FRPar.Imp(fm_of_term m m' p, fm_of_term m m' q)
  3023   | Const("op -->",_)$p$q => @{code Imp} (fm_of_term m m' p, fm_of_term m m' q)
  3037   | Const("op =",ty)$p$q => 
  3024   | Const("op =",ty)$p$q => 
  3038        if domain_type ty = bT then FRPar.Iff(fm_of_term m m' p, fm_of_term m m' q)
  3025        if domain_type ty = bT then @{code Iff} (fm_of_term m m' p, fm_of_term m m' q)
  3039        else FRPar.Eq (FRPar.tm_Sub(tm_of_term m m' p, tm_of_term m m' q))
  3026        else @{code Eq} (@{code Sub} (tm_of_term m m' p, tm_of_term m m' q))
  3040   | Const(@{const_name Algebras.less},_)$p$q => 
  3027   | Const(@{const_name Algebras.less},_)$p$q => 
  3041         FRPar.Lt (FRPar.tm_Sub(tm_of_term m m' p, tm_of_term m m' q))
  3028         @{code Lt} (@{code Sub} (tm_of_term m m' p, tm_of_term m m' q))
  3042   | Const(@{const_name Algebras.less_eq},_)$p$q => 
  3029   | Const(@{const_name Algebras.less_eq},_)$p$q => 
  3043         FRPar.Le (FRPar.tm_Sub(tm_of_term m m' p, tm_of_term m m' q))
  3030         @{code Le} (@{code Sub} (tm_of_term m m' p, tm_of_term m m' q))
  3044   | Const("Ex",_)$Abs(xn,xT,p) => 
  3031   | Const("Ex",_)$Abs(xn,xT,p) => 
  3045      let val (xn', p') =  variant_abs (xn,xT,p)
  3032      let val (xn', p') =  variant_abs (xn,xT,p)
  3046          val x = Free(xn',xT)
  3033          val x = Free(xn',xT)
  3047          fun incr i = i + 1
  3034          fun incr i = i + 1
  3048          val m0 = (x,0):: (map (apsnd incr) m)
  3035          val m0 = (x,0):: (map (apsnd incr) m)
  3049       in FRPar.E (fm_of_term m0 m' p') end
  3036       in @{code E} (fm_of_term m0 m' p') end
  3050   | Const("All",_)$Abs(xn,xT,p) => 
  3037   | Const("All",_)$Abs(xn,xT,p) => 
  3051      let val (xn', p') =  variant_abs (xn,xT,p)
  3038      let val (xn', p') =  variant_abs (xn,xT,p)
  3052          val x = Free(xn',xT)
  3039          val x = Free(xn',xT)
  3053          fun incr i = i + 1
  3040          fun incr i = i + 1
  3054          val m0 = (x,0):: (map (apsnd incr) m)
  3041          val m0 = (x,0):: (map (apsnd incr) m)
  3055       in FRPar.A (fm_of_term m0 m' p') end
  3042       in @{code A} (fm_of_term m0 m' p') end
  3056   | _ => error "fm_of_term";
  3043   | _ => error "fm_of_term";
  3057 
  3044 
  3058 
  3045 
  3059 fun term_of_fm T m m' t = 
  3046 fun term_of_fm T m m' t = 
  3060   case t of
  3047   case t of
  3061     FRPar.T => Const("True",bT)
  3048     @{code T} => Const("True",bT)
  3062   | FRPar.F => Const("False",bT)
  3049   | @{code F} => Const("False",bT)
  3063   | FRPar.NOT p => nott $ (term_of_fm T m m' p)
  3050   | @{code NOT} p => nott $ (term_of_fm T m m' p)
  3064   | FRPar.And (p,q) => conjt $ (term_of_fm T m m' p) $ (term_of_fm T m m' q)
  3051   | @{code And} (p,q) => conjt $ (term_of_fm T m m' p) $ (term_of_fm T m m' q)
  3065   | FRPar.Or (p,q) => disjt $ (term_of_fm T m m' p) $ (term_of_fm T m m' q)
  3052   | @{code Or} (p,q) => disjt $ (term_of_fm T m m' p) $ (term_of_fm T m m' q)
  3066   | FRPar.Imp (p,q) => impt $ (term_of_fm T m m' p) $ (term_of_fm T m m' q)
  3053   | @{code Imp} (p,q) => impt $ (term_of_fm T m m' p) $ (term_of_fm T m m' q)
  3067   | FRPar.Iff (p,q) => ifft $ (term_of_fm T m m' p) $ (term_of_fm T m m' q)
  3054   | @{code Iff} (p,q) => ifft $ (term_of_fm T m m' p) $ (term_of_fm T m m' q)
  3068   | FRPar.Lt p => (llt T) $ (term_of_tm T m m' p) $ (rz T)
  3055   | @{code Lt} p => (llt T) $ (term_of_tm T m m' p) $ (rz T)
  3069   | FRPar.Le p => (lle T) $ (term_of_tm T m m' p) $ (rz T)
  3056   | @{code Le} p => (lle T) $ (term_of_tm T m m' p) $ (rz T)
  3070   | FRPar.Eq p => (eqt T) $ (term_of_tm T m m' p) $ (rz T)
  3057   | @{code Eq} p => (eqt T) $ (term_of_tm T m m' p) $ (rz T)
  3071   | FRPar.NEq p => nott $ ((eqt T) $ (term_of_tm T m m' p) $ (rz T))
  3058   | @{code NEq} p => nott $ ((eqt T) $ (term_of_tm T m m' p) $ (rz T))
  3072   | _ => error "term_of_fm: quantifiers!!!!???";
  3059   | _ => error "term_of_fm: quantifiers!!!!???";
  3073 
  3060 
  3074 fun frpar_oracle (T,m, m', fm) = 
  3061 fun frpar_oracle (T,m, m', fm) = 
  3075  let 
  3062  let 
  3076    val t = HOLogic.dest_Trueprop fm
  3063    val t = HOLogic.dest_Trueprop fm
  3077    val im = 0 upto (length m - 1)
  3064    val im = 0 upto (length m - 1)
  3078    val im' = 0 upto (length m' - 1)   
  3065    val im' = 0 upto (length m' - 1)   
  3079  in HOLogic.mk_Trueprop (HOLogic.mk_eq(t, term_of_fm T (im ~~ m) (im' ~~ m')  
  3066  in HOLogic.mk_Trueprop (HOLogic.mk_eq(t, term_of_fm T (im ~~ m) (im' ~~ m')  
  3080                                                      (FRPar.frpar (fm_of_term (m ~~ im) (m' ~~ im') t))))
  3067                                                      (@{code frpar} (fm_of_term (m ~~ im) (m' ~~ im') t))))
  3081  end;
  3068  end;
  3082 
  3069 
  3083 fun frpar_oracle2 (T,m, m', fm) = 
  3070 fun frpar_oracle2 (T,m, m', fm) = 
  3084  let 
  3071  let 
  3085    val t = HOLogic.dest_Trueprop fm
  3072    val t = HOLogic.dest_Trueprop fm
  3086    val im = 0 upto (length m - 1)
  3073    val im = 0 upto (length m - 1)
  3087    val im' = 0 upto (length m' - 1)   
  3074    val im' = 0 upto (length m' - 1)   
  3088  in HOLogic.mk_Trueprop (HOLogic.mk_eq(t, term_of_fm T (im ~~ m) (im' ~~ m')  
  3075  in HOLogic.mk_Trueprop (HOLogic.mk_eq(t, term_of_fm T (im ~~ m) (im' ~~ m')  
  3089                                                      (FRPar.frpar2 (fm_of_term (m ~~ im) (m' ~~ im') t))))
  3076                                                      (@{code frpar2} (fm_of_term (m ~~ im) (m' ~~ im') t))))
  3090  end;
  3077  end;
  3091 
  3078 
  3092 end;
  3079 end;
  3093 
  3080 
  3094 
  3081