src/HOL/ex/reflection.ML
changeset 23548 e25991f126ce
parent 22568 ed7aa5a350ef
child 23605 81d0fdec9edc
equal deleted inserted replaced
23547:cb1203d8897c 23548:e25991f126ce
    10   val reflection_tac: Proof.context -> thm list -> term option -> int -> tactic
    10   val reflection_tac: Proof.context -> thm list -> term option -> int -> tactic
    11   val gen_reflection_tac: Proof.context -> (cterm -> thm)
    11   val gen_reflection_tac: Proof.context -> (cterm -> thm)
    12     -> thm list -> term option -> int -> tactic
    12     -> thm list -> term option -> int -> tactic
    13 end;
    13 end;
    14 
    14 
    15 structure Reflection : REFLECTION
    15 structure Reflection(* : REFLECTION *)
    16 = struct
    16 = struct
       
    17 
       
    18 val my_term = ref @{term "STUPPID"};
       
    19 val my_eqs = ref ([]: thm list);
       
    20 val my_ctxt = ref @{context};
    17 
    21 
    18 val ext2 = thm "ext2";
    22 val ext2 = thm "ext2";
    19 val nth_Cons_0 = thm "nth_Cons_0";
    23 val nth_Cons_0 = thm "nth_Cons_0";
    20 val nth_Cons_Suc = thm "nth_Cons_Suc";
    24 val nth_Cons_Suc = thm "nth_Cons_Suc";
    21 
    25 
   149     end)
   153     end)
   150       handle MATCH => decomp_genreif da congs (t,ctxt)))
   154       handle MATCH => decomp_genreif da congs (t,ctxt)))
   151   end;
   155   end;
   152           (* looks for the atoms equation and instantiates it with the right number *)
   156           (* looks for the atoms equation and instantiates it with the right number *)
   153 
   157 
       
   158 
   154 fun mk_decompatom eqs (t,ctxt) =
   159 fun mk_decompatom eqs (t,ctxt) =
   155  let 
   160  let 
   156   val tT = fastype_of t
   161   val tT = fastype_of t
   157   fun isat eq = 
   162   fun isat eq = 
   158    let 
   163    let 
   161 	  (fn (n,ty) => n="List.nth" 
   166 	  (fn (n,ty) => n="List.nth" 
   162 			andalso 
   167 			andalso 
   163 			AList.defined Type.could_unify (!bds) (domain_type ty)) rhs 
   168 			AList.defined Type.could_unify (!bds) (domain_type ty)) rhs 
   164 	  andalso Type.could_unify (fastype_of rhs, tT)
   169 	  andalso Type.could_unify (fastype_of rhs, tT)
   165    end
   170    end
   166   fun get_nth t = 
   171   fun get_nths t acc = 
   167    case t of
   172    case t of
   168      Const("List.nth",_)$vs$n => (t,vs,n)
   173      Const("List.nth",_)$vs$n => insert (fn ((a,_),(b,_)) => a aconv b) (t,(vs,n)) acc
   169    | t1$t2 => (get_nth t1 handle REIF "get_nth" => get_nth t2)
   174    | t1$t2 => get_nths t1 (get_nths t2 acc)
   170    | Abs(_,_,t') => get_nth t'
   175    | Abs(_,_,t') => get_nths t'  acc
   171    | _ => raise REIF "get_nth"
   176    | _ => acc
   172   val ([xn,vsn],ctxt') = Variable.variant_fixes ["x","vs"] ctxt
   177 
   173   val thy = ProofContext.theory_of ctxt'
   178 
   174   val cert = cterm_of thy
   179   fun tryeqs [] = error "Can not find the atoms equation"
   175   fun tryeqs [] = raise REIF "Can not find the atoms equation"
       
   176     | tryeqs (eq::eqs) = ((
   180     | tryeqs (eq::eqs) = ((
   177       let 
   181       let 
   178        val rhs = eq |> prop_of |> HOLogic.dest_Trueprop 
   182         val rhs = eq |> prop_of |> HOLogic.dest_Trueprop  |> HOLogic.dest_eq |> snd
   179 			  |> HOLogic.dest_eq |> snd
   183  val nths = get_nths rhs []
   180        val (nt,vs,n) = get_nth rhs
   184  val (vss,ns) = fold_rev (fn (_,(vs,n)) => fn (vss,ns) => (insert (op aconv) vs vss, insert (op aconv) n ns)) nths ([],[]) 
   181        val ntT = fastype_of nt
   185  val (vsns, ctxt') = Variable.variant_fixes (replicate (length vss) "vs") ctxt
   182        val ntlT = HOLogic.listT ntT
   186  val (xns, ctxt'') = Variable.variant_fixes (replicate (length nths) "x") ctxt' 
   183        val (bsT,asT) = the (AList.lookup (op =) (!bds) ntlT) 
   187   val thy = ProofContext.theory_of ctxt''
   184        val x = Var ((xn,0),ntT)
   188   val cert = cterm_of thy
   185        val rhs_P = subst_free [(nt,x)] rhs
   189  val vsns_map = vss ~~ vsns
   186        val (_, tmenv) = Pattern.match 
   190  val xns_map = (fst (split_list nths)) ~~ xns
   187 			    thy (rhs_P, t)
   191         val subst = map (fn (nt, xn) => (nt, Var ((xn,0), fastype_of nt))) xns_map
   188 			    (Envir.type_env (Envir.empty 0),Term.Vartab.empty)
   192         val rhs_P = subst_free subst rhs
   189        val tml = Vartab.dest tmenv
   193         val (_, tmenv) = Pattern.match 
   190        val SOME (_,t') = AList.lookup (op =) tml (xn,0)
   194 	    thy (rhs_P, t)
   191        val cvs = 
   195 	   (Envir.type_env (Envir.empty 0),Term.Vartab.empty)
   192 	   cert (fold_rev (fn x => fn xs => Const("List.list.Cons", ntT --> ntlT --> ntlT)$x$xs)
   196         val tml = Vartab.dest tmenv
   193 		       bsT (Free (vsn, ntlT)))
   197         val t's = map (fn xn => snd (valOf (AList.lookup (op =) tml (xn,0)))) xns
       
   198         val subst_ns = map (fn (Const _ $ vs $ n, Var (xn0,T)) => (cert n, snd (valOf (AList.lookup (op =) tml xn0)) |> (index_of #> IntInf.fromInt #> HOLogic.mk_nat #> cert))) subst
       
   199         val subst_vs = 
       
   200          let 
       
   201            fun h (Const _ $ (vs as Var (vsn,lT)) $ n, Var (xn0,T)) = 
       
   202             let 
       
   203              val (bsT,asT) = the (AList.lookup (op =) (!bds) lT)
       
   204              val vsn = valOf (AList.lookup (op =) vsns_map vs)
       
   205              val cvs = 
       
   206 	       cert (fold_rev (fn x => fn xs => Const("List.list.Cons", T --> lT --> lT)$x$xs) bsT (Free (vsn, lT)))
       
   207 
       
   208          in (cert vs, cvs) end
       
   209         in map h subst end
   194        val cts = map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) 
   210        val cts = map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) 
   195 		     (AList.delete (op =) (xn,0) tml)
   211          (fold (AList.delete (fn (((a: string),_),(b,_)) => a = b)) (map (fn n => (n,0)) xns) tml)
   196        val th = (instantiate 
   212 
   197 		     ([],
   213        val th = (instantiate ([],subst_ns@subst_vs@cts)  eq) RS sym
   198 		      [(cert vs, cvs),(cert n, t' |> index_of |> IntInf.fromInt |> HOLogic.mk_nat |> cert)]
   214      in  hd (Variable.export ctxt'' ctxt [th]) end)
   199 		      @cts) eq) RS sym
       
   200       in hd (Variable.export ctxt' ctxt [th])
       
   201       end)
       
   202 	  handle MATCH => tryeqs eqs)
   215 	  handle MATCH => tryeqs eqs)
   203  in ([], fn _ => tryeqs (filter isat eqs))
   216  in ([], fn _ => tryeqs (filter isat eqs))
   204  end;
   217  end;
   205 
   218 
   206 (* 
       
   207 fun mk_decompatom eqs (t,ctxt) =
       
   208  let 
       
   209   val tT = fastype_of t
       
   210   val tlT = HOLogic.listT tT
       
   211   val (bsT,asT) = (the (AList.lookup (op =) (!bds) tlT) 
       
   212 		   handle Option => error "mk_decompatom: Type not found in the env.")
       
   213   fun isateq (_$_$(Const("List.nth",_)$vs$_)) = (fastype_of vs = tlT)
       
   214     | isateq _ = false
       
   215  in case List.find (isateq o HOLogic.dest_Trueprop o prop_of) eqs of
       
   216      NONE => raise REIF "Can not find the atoms equation"
       
   217    | SOME th =>
       
   218      ([],
       
   219       fn ths =>
       
   220         let 
       
   221          val ([x], ctxt') = Variable.variant_fixes ["vs"] ctxt
       
   222 	 val cert = cterm_of (ProofContext.theory_of ctxt')
       
   223          val (Const("List.nth",_)$(vs as Var((vsn,vsi),_))$n) = 
       
   224              (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of) th
       
   225          val cvs = 
       
   226 	     cert (foldr (fn (x,xs) => Const("List.list.Cons", tT --> tlT --> tlT)$x$xs) 
       
   227 			 (Free(x,tlT)) bsT)
       
   228 	 val th' = (instantiate ([],
       
   229 				 [(cert vs, cvs), 
       
   230 				  (cert n, cert  (HOLogic.mk_nat(index_of t)))]) th)
       
   231 		       RS sym
       
   232         in hd (Variable.export ctxt' ctxt [th']) end)
       
   233  end;
       
   234 *)
       
   235   (* Generic reification procedure: *)
   219   (* Generic reification procedure: *)
   236   (* creates all needed cong rules and then just uses the theorem synthesis *)
   220   (* creates all needed cong rules and then just uses the theorem synthesis *)
   237 
   221 
   238 fun mk_congs ctxt raw_eqs = 
   222 fun mk_congs ctxt raw_eqs = 
   239  let 
   223  let 
   261  in  ps ~~ (Variable.export ctxt' ctxt congs)
   245  in  ps ~~ (Variable.export ctxt' ctxt congs)
   262  end;
   246  end;
   263 
   247 
   264 fun genreif ctxt raw_eqs t =
   248 fun genreif ctxt raw_eqs t =
   265  let 
   249  let 
       
   250     val _ = my_eqs := raw_eqs
       
   251     val _ = my_term := t
       
   252     val my_ctxt = ctxt
   266   val _ = bds := []
   253   val _ = bds := []
   267   val congs = mk_congs ctxt raw_eqs
   254   val congs = mk_congs ctxt raw_eqs
   268   val th = divide_and_conquer (decomp_genreif (mk_decompatom raw_eqs) congs) (t,ctxt)
   255   val th = divide_and_conquer (decomp_genreif (mk_decompatom raw_eqs) congs) (t,ctxt)
   269   val tys = th |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd
   256   val tys = th |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd
   270 	       |> strip_comb |> fst |> fastype_of |> strip_type |> fst
   257 	       |> strip_comb |> fst |> fastype_of |> strip_type |> fst
   306     val th = genreflect ctxt conv corr_thm raw_eqs t
   293     val th = genreflect ctxt conv corr_thm raw_eqs t
   307       RS ssubst;
   294       RS ssubst;
   308   in rtac th i st end);
   295   in rtac th i st end);
   309 
   296 
   310 fun reflection_tac ctxt = gen_reflection_tac ctxt NBE.normalization_conv;
   297 fun reflection_tac ctxt = gen_reflection_tac ctxt NBE.normalization_conv;
   311 
       
   312 end
   298 end