src/HOL/ex/ReflectionEx.thy
changeset 20564 6857bd9f1a79
parent 20503 503ac4c5ef91
child 22199 b617ddd200eb
equal deleted inserted replaced
20563:44eda2314aab 20564:6857bd9f1a79
   111   Inum_Add: "Inum vs (Add s t) = Inum vs s + Inum vs t"
   111   Inum_Add: "Inum vs (Add s t) = Inum vs s + Inum vs t"
   112   Inum_Mul: "Inum vs (Mul c t) = c * Inum vs t"
   112   Inum_Mul: "Inum vs (Mul c t) = c * Inum vs t"
   113   Inum_CN : "Inum vs (CN n c t) = c*(vs!n) + Inum vs t"
   113   Inum_CN : "Inum vs (CN n c t) = c*(vs!n) + Inum vs t"
   114 
   114 
   115   text{* Let's reify some nat expressions \<dots> *}
   115   text{* Let's reify some nat expressions \<dots> *}
   116 lemma "4 * (2*x + (y::nat)) \<noteq> 0"
   116 lemma "4 * (2*x + (y::nat)) + f a \<noteq> 0"
   117   apply (reify Inum.simps ("4 * (2*x + (y::nat))"))
   117   apply (reify Inum.simps ("4 * (2*x + (y::nat)) + f a"))
   118 oops
   118 oops
   119 text{* We're in a bad situation!! The term above has been recongnized as a constant, which is correct but does not correspond to our intuition of the constructor C. It should encapsulate constants, i.e. numbers, i.e. numerals.*}
   119 text{* We're in a bad situation!! The term above has been recongnized as a constant, which is correct but does not correspond to our intuition of the constructor C. It should encapsulate constants, i.e. numbers, i.e. numerals.*}
   120 
   120 
   121   text{* So let's leave the Inum_C equation at the end and see what happens \<dots>*}
   121   text{* So let's leave the Inum_C equation at the end and see what happens \<dots>*}
   122 lemma "4 * (2*x + (y::nat)) \<noteq> 0"
   122 lemma "4 * (2*x + (y::nat)) \<noteq> 0"
   171   "lin_mul (C j) = (\<lambda> i. C (i*j))"
   171   "lin_mul (C j) = (\<lambda> i. C (i*j))"
   172   "lin_mul (CN n c a) = (\<lambda> i. if i=0 then (C 0) else CN n (i*c) (lin_mul a i))"
   172   "lin_mul (CN n c a) = (\<lambda> i. if i=0 then (C 0) else CN n (i*c) (lin_mul a i))"
   173   "lin_mul t = (\<lambda> i. Mul i t)"
   173   "lin_mul t = (\<lambda> i. Mul i t)"
   174 
   174 
   175 lemma lin_mul: "Inum bs (lin_mul t i) = Inum bs (Mul i t)"
   175 lemma lin_mul: "Inum bs (lin_mul t i) = Inum bs (Mul i t)"
   176 by (induct t arbitrary: i rule: lin_mul.induct) (auto simp add: ring_eq_simps)
   176 by (induct t arbitrary: i rule: lin_mul.induct, auto simp add: ring_eq_simps)
   177 
   177 
   178 consts linum:: "num \<Rightarrow> num"
   178 consts linum:: "num \<Rightarrow> num"
   179 recdef linum "measure num_size"
   179 recdef linum "measure num_size"
   180   "linum (C b) = C b"
   180   "linum (C b) = C b"
   181   "linum (Var n) = CN n 1 (C 0)"
   181   "linum (Var n) = CN n 1 (C 0)"
   186 lemma linum : "Inum vs (linum t) = Inum vs t"
   186 lemma linum : "Inum vs (linum t) = Inum vs t"
   187 by (induct t rule: linum.induct, simp_all add: lin_mul lin_add)
   187 by (induct t rule: linum.induct, simp_all add: lin_mul lin_add)
   188 
   188 
   189   text{* Now we can use linum to simplify nat terms using reflection *}
   189   text{* Now we can use linum to simplify nat terms using reflection *}
   190 lemma "(Suc (Suc 1)) * (x + (Suc 1)*y) = 3*x + 6*y"
   190 lemma "(Suc (Suc 1)) * (x + (Suc 1)*y) = 3*x + 6*y"
   191 apply (reflection linum Inum_eqs' ("(Suc (Suc 1)) * (x + (Suc 1)*y)"))
   191 (* apply (reflection linum Inum_eqs' ("(Suc (Suc 1)) * (x + (Suc 1)*y)")) *)
   192 oops
   192 oops
   193 
   193 
   194   text{* Let's lift this to formulae and see what happens *}
   194   text{* Let's lift this to formulae and see what happens *}
   195 
   195 
   196 datatype aform = Lt num num  | Eq num num | Ge num num | NEq num num | 
   196 datatype aform = Lt num num  | Eq num num | Ge num num | NEq num num | 
   218   "aform vs (NEq a b) = (Inum vs a \<noteq> Inum vs b)"
   218   "aform vs (NEq a b) = (Inum vs a \<noteq> Inum vs b)"
   219   "aform vs (NEG p) = (\<not> (aform vs p))"
   219   "aform vs (NEG p) = (\<not> (aform vs p))"
   220   "aform vs (Conj p q) = (aform vs p \<and> aform vs q)"
   220   "aform vs (Conj p q) = (aform vs p \<and> aform vs q)"
   221   "aform vs (Disj p q) = (aform vs p \<or> aform vs q)"
   221   "aform vs (Disj p q) = (aform vs p \<or> aform vs q)"
   222 
   222 
   223   text{* Let's reify and do reflection. *}
   223   text{* Let's reify and do reflection *}
   224 lemma "(3::nat)*x + t < 0 \<and> (2 * x + y \<noteq> 17)"
   224 lemma "(3::nat)*x + t < 0 \<and> (2 * x + y \<noteq> 17)"
   225 apply (reify Inum_eqs' aform.simps)
   225 (* apply (reify Inum_eqs' aform.simps) *)
   226 oops
   226 oops
   227 
   227 
   228 text{* Note that reification handles several interpretations at the same time*}
   228 text{* Note that reification handles several interpretations at the same time*}
   229 lemma "(3::nat)*x + t < 0 & x*x + t*x + 3 + 1 = z*t*4*z | x + x + 1 < 0"
   229 lemma "(3::nat)*x + t < 0 & x*x + t*x + 3 + 1 = z*t*4*z | x + x + 1 < 0"
   230 apply (reflection linum Inum_eqs' aform.simps ("x + x + 1"))
   230 (* apply (reflection linum Inum_eqs' aform.simps ("x + x + 1")) *)
   231 oops
   231 oops
   232 
   232 
   233   text{* For reflection we now define a simple transformation on aform: NNF + linum on atoms *}
   233   text{* For reflection we now define a simple transformation on aform: NNF + linum on atoms *}
   234 consts linaform:: "aform \<Rightarrow> aform"
   234 consts linaform:: "aform \<Rightarrow> aform"
   235 recdef linaform "measure linaformsize"
   235 recdef linaform "measure linaformsize"
   252 
   252 
   253 lemma linaform: "aform vs (linaform p) = aform vs p"
   253 lemma linaform: "aform vs (linaform p) = aform vs p"
   254   by (induct p rule: linaform.induct, auto simp add: linum)
   254   by (induct p rule: linaform.induct, auto simp add: linum)
   255 
   255 
   256 lemma "(((Suc(Suc (Suc 0)))*((x::nat) + (Suc (Suc 0)))) + (Suc (Suc (Suc 0))) * ((Suc(Suc (Suc 0)))*((x::nat) + (Suc (Suc 0))))< 0) \<and> (Suc 0  + Suc 0< 0)"
   256 lemma "(((Suc(Suc (Suc 0)))*((x::nat) + (Suc (Suc 0)))) + (Suc (Suc (Suc 0))) * ((Suc(Suc (Suc 0)))*((x::nat) + (Suc (Suc 0))))< 0) \<and> (Suc 0  + Suc 0< 0)"
   257   apply (reflection linaform Inum_eqs' aform.simps) 
   257 (*   apply (reflection linaform Inum_eqs' aform.simps)  *)
   258 oops
   258 oops
   259 
   259 
   260 
   260 text{* We now give an example where Interpretaions have 0 or more than only one envornement of different types and show that automatic reification also deals with binding *}
   261 text{* And finally an example for binders. Here we have an existential quantifier. Binding is trough de Bruijn indices, the index of the varibles. *}
   261 datatype rb = BC bool| BAnd rb rb | BOr rb rb
   262 
   262 consts Irb :: "rb \<Rightarrow> bool"
   263 datatype afm = LT num num | EQ num | AND afm afm | OR afm afm | E afm | A afm
   263 primrec
   264 
   264   "Irb (BAnd s t) = (Irb s \<and> Irb t)"
   265 consts Iafm:: "nat list \<Rightarrow> afm \<Rightarrow> bool"
   265   "Irb (BOr s t) = (Irb s \<or> Irb t)"
   266 
   266   "Irb (BC p) = p"
   267 primrec
   267 
   268   "Iafm vs (LT s t) = (Inum vs s < Inum vs t)"
   268 lemma "A \<and> (B \<or> D \<and> B) \<and> A \<and> (B \<or> D \<and> B) \<or> A \<and> (B \<or> D \<and> B) \<or> A \<and> (B \<or> D \<and> B)"
   269   "Iafm vs (EQ t) = (Inum vs t = 0)"
   269 apply (reify Irb.simps)
   270   "Iafm vs (AND p q) = (Iafm vs p \<and> Iafm vs q)"
   270 oops
   271   "Iafm vs (OR p q) = (Iafm vs p \<or> Iafm vs q)"
   271 
   272   "Iafm vs (E p) = (\<exists>x. Iafm (x#vs) p)"
   272 datatype rint = IC int| IVar nat | IAdd rint rint | IMult rint rint | INeg rint | ISub rint rint
   273   "Iafm vs (A p) = (\<forall>x. Iafm (x#vs) p)"
   273 consts Irint :: "int list \<Rightarrow> rint \<Rightarrow> int"
   274 
   274 primrec
   275 lemma " \<forall>(x::nat) y. \<exists> z. z < x + 3*y \<and> x + y = 0"
   275 Irint_Var: "Irint vs (IVar n) = vs!n"
   276 apply (reify Inum_eqs' Iafm.simps)
   276 Irint_Neg: "Irint vs (INeg t) = - Irint vs t"
   277 oops
   277 Irint_Add: "Irint vs (IAdd s t) = Irint vs s + Irint vs t"
   278 
   278 Irint_Sub: "Irint vs (ISub s t) = Irint vs s - Irint vs t"
   279 
   279 Irint_Mult: "Irint vs (IMult s t) = Irint vs s * Irint vs t"
       
   280 Irint_C: "Irint vs (IC i) = i"
       
   281 lemma Irint_C0: "Irint vs (IC 0) = 0"
       
   282   by simp
       
   283 lemma Irint_C1: "Irint vs (IC 1) = 1"
       
   284   by simp
       
   285 lemma Irint_Cnumberof: "Irint vs (IC (number_of x)) = number_of x"
       
   286   by simp
       
   287 lemmas Irint_simps = Irint_Var Irint_Neg Irint_Add Irint_Sub Irint_Mult Irint_C0 Irint_C1 Irint_Cnumberof 
       
   288 lemma "(3::int) * x + y*y - 9 + (- z) = 0"
       
   289   apply (reify Irint_simps ("(3::int) * x + y*y - 9 + (- z)"))
       
   290   oops
       
   291 datatype rlist = LVar nat| LEmpty| LCons rint rlist | LAppend rlist rlist
       
   292 consts Irlist :: "int list \<Rightarrow> (int list) list \<Rightarrow> rlist \<Rightarrow> (int list)"
       
   293 primrec
       
   294   "Irlist is vs (LEmpty) = []"
       
   295   "Irlist is vs (LVar n) = vs!n"
       
   296   "Irlist is vs (LCons i t) = ((Irint is i)#(Irlist is vs t))"
       
   297   "Irlist is vs (LAppend s t) = (Irlist is vs s) @ (Irlist is vs t)"
       
   298 lemma "[(1::int)] = []"
       
   299   apply (reify Irlist.simps Irint_simps ("[1]:: int list"))
       
   300   oops
       
   301 
       
   302 lemma "([(3::int) * x + y*y - 9 + (- z)] @ []) @ xs = [y*y - z - 9 + (3::int) * x]"
       
   303   apply (reify Irlist.simps Irint_simps ("([(3::int) * x + y*y - 9 + (- z)] @ []) @ xs"))
       
   304   oops
       
   305 
       
   306 datatype rnat = NC nat| NVar nat| NSuc rnat | NAdd rnat rnat | NMult rnat rnat | NNeg rnat | NSub rnat rnat | Nlgth rlist
       
   307 consts Irnat :: "int list \<Rightarrow> (int list) list \<Rightarrow> nat list \<Rightarrow> rnat \<Rightarrow> nat"
       
   308 primrec
       
   309 Irnat_Suc: "Irnat is ls vs (NSuc t) = Suc (Irnat is ls vs t)"
       
   310 Irnat_Var: "Irnat is ls vs (NVar n) = vs!n"
       
   311 Irnat_Neg: "Irnat is ls vs (NNeg t) = - Irnat is ls vs t"
       
   312 Irnat_Add: "Irnat is ls vs (NAdd s t) = Irnat is ls vs s + Irnat is ls vs t"
       
   313 Irnat_Sub: "Irnat is ls vs (NSub s t) = Irnat is ls vs s - Irnat is ls vs t"
       
   314 Irnat_Mult: "Irnat is ls vs (NMult s t) = Irnat is ls vs s * Irnat is ls vs t"
       
   315 Irnat_lgth: "Irnat is ls vs (Nlgth rxs) = length (Irlist is ls rxs)"
       
   316 Irnat_C: "Irnat is ls vs (NC i) = i"
       
   317 lemma Irnat_C0: "Irnat is ls vs (NC 0) = 0"
       
   318 by simp
       
   319 lemma Irnat_C1: "Irnat is ls vs (NC 1) = 1"
       
   320 by simp
       
   321 lemma Irnat_Cnumberof: "Irnat is ls vs (NC (number_of x)) = number_of x"
       
   322 by simp
       
   323 lemmas Irnat_simps = Irnat_Suc Irnat_Var Irnat_Neg Irnat_Add Irnat_Sub Irnat_Mult Irnat_lgth
       
   324   Irnat_C0 Irnat_C1 Irnat_Cnumberof
       
   325 lemma "(Suc n) * length (([(3::int) * x + y*y - 9 + (- z)] @ []) @ xs) = length xs"
       
   326   apply (reify Irnat_simps Irlist.simps Irint_simps ("(Suc n) *length (([(3::int) * x + y*y - 9 + (- z)] @ []) @ xs)"))
       
   327   oops
       
   328 datatype rifm = RT | RF | RVar nat
       
   329   | RNLT rnat rnat | RNILT rnat rint | RNEQ rnat rnat
       
   330   |RAnd rifm rifm | ROr rifm rifm | RImp rifm rifm| RIff rifm rifm
       
   331   | RNEX rifm | RIEX rifm| RLEX rifm | RNALL rifm | RIALL rifm| RLALL rifm
       
   332   | RBEX rifm | RBALL rifm
       
   333 consts Irifm :: "bool list \<Rightarrow> int list \<Rightarrow> (int list) list \<Rightarrow> nat list \<Rightarrow> rifm \<Rightarrow> bool"
       
   334 primrec
       
   335 "Irifm ps is ls ns RT = True"
       
   336 "Irifm ps is ls ns RF = False"
       
   337   "Irifm ps is ls ns (RVar n) = ps!n"
       
   338 "Irifm ps is ls ns (RNLT s t) = (Irnat is ls ns s < Irnat is ls ns t)"
       
   339 "Irifm ps is ls ns (RNILT s t) = (int (Irnat is ls ns s) < Irint is t)"
       
   340 "Irifm ps is ls ns (RNEQ s t) = (Irnat is ls ns s = Irnat is ls ns t)"
       
   341 "Irifm ps is ls ns (RAnd p q) = (Irifm ps is ls ns p \<and> Irifm ps is ls ns q)"
       
   342 "Irifm ps is ls ns (ROr p q) = (Irifm ps is ls ns p \<or> Irifm ps is ls ns q)"
       
   343 "Irifm ps is ls ns (RImp p q) = (Irifm ps is ls ns p \<longrightarrow> Irifm ps is ls ns q)"
       
   344 "Irifm ps is ls ns (RIff p q) = (Irifm ps is ls ns p = Irifm ps is ls ns q)"
       
   345 "Irifm ps is ls ns (RNEX p) =  (\<exists>x. Irifm ps is ls (x#ns) p)"
       
   346 "Irifm ps is ls ns (RIEX p) =  (\<exists>x. Irifm ps (x#is) ls ns p)"
       
   347 "Irifm ps is ls ns (RLEX p) =  (\<exists>x. Irifm ps is (x#ls) ns p)"
       
   348 "Irifm ps is ls ns (RBEX p) =  (\<exists>x. Irifm (x#ps) is ls ns p)"
       
   349 "Irifm ps is ls ns (RNALL p) = (\<forall>x. Irifm ps is ls (x#ns) p)"
       
   350 "Irifm ps is ls ns (RIALL p) = (\<forall>x. Irifm ps (x#is) ls ns p)"
       
   351 "Irifm ps is ls ns (RLALL p) = (\<forall>x. Irifm ps is (x#ls) ns p)"
       
   352 "Irifm ps is ls ns (RBALL p) = (\<forall>x. Irifm (x#ps) is ls ns p)"
       
   353 
       
   354 lemma " \<forall>x. \<exists>n. ((Suc n) * length (([(3::int) * x + (f t)*y - 9 + (- z)] @ []) @ xs) = length xs) \<and> m < 5*n - length (xs @ [2,3,4,x*z + 8 - y]) \<longrightarrow> (\<exists>p. \<forall>q. p \<and> q \<longrightarrow> r)"
       
   355   apply (reify Irifm.simps Irnat_simps Irlist.simps Irint_simps)
       
   356 oops
   280 
   357 
   281 end
   358 end