src/Tools/coherent.ML
changeset 55632 0f9d03649a9c
parent 55631 7f428e08111b
child 55634 306ff289da3a
equal deleted inserted replaced
55631:7f428e08111b 55632:0f9d03649a9c
    18   val operator_names: string list
    18   val operator_names: string list
    19 end;
    19 end;
    20 
    20 
    21 signature COHERENT =
    21 signature COHERENT =
    22 sig
    22 sig
    23   val verbose: bool Unsynchronized.ref
    23   val trace: bool Config.T
    24   val coherent_tac: Proof.context -> thm list -> int -> tactic
    24   val coherent_tac: Proof.context -> thm list -> int -> tactic
    25   val setup: theory -> theory
       
    26 end;
    25 end;
    27 
    26 
    28 functor Coherent(Data: COHERENT_DATA) : COHERENT =
    27 functor Coherent(Data: COHERENT_DATA) : COHERENT =
    29 struct
    28 struct
    30 
    29 
    31 (** misc tools **)
    30 (** misc tools **)
    32 
    31 
    33 val verbose = Unsynchronized.ref false;
    32 val (trace, trace_setup) = Attrib.config_bool @{binding coherent_trace} (K false);
    34 
    33 fun cond_trace ctxt msg = if Config.get ctxt trace then tracing (msg ()) else ();
    35 fun message f = if !verbose then tracing (f ()) else ();
       
    36 
    34 
    37 datatype cl_prf =
    35 datatype cl_prf =
    38   ClPrf of thm * (Type.tyenv * Envir.tenv) * ((indexname * typ) * term) list *
    36   ClPrf of thm * (Type.tyenv * Envir.tenv) * ((indexname * typ) * term) list *
    39   int list * (term list * cl_prf) list;
    37   int list * (term list * cl_prf) list;
    40 
    38 
   145   end
   143   end
   146 
   144 
   147 and valid_cases _ _ _ _ _ _ _ [] = SOME []
   145 and valid_cases _ _ _ _ _ _ _ [] = SOME []
   148   | valid_cases ctxt rules goal dom facts nfacts nparams ((Ts, ts) :: ds) =
   146   | valid_cases ctxt rules goal dom facts nfacts nparams ((Ts, ts) :: ds) =
   149       let
   147       let
   150         val _ = message (fn () => "case " ^ commas (map (Syntax.string_of_term ctxt) ts));
   148         val _ = cond_trace ctxt (fn () => "case " ^ commas (map (Syntax.string_of_term ctxt) ts));
   151         val params = map_index (fn (i, T) => Free ("par" ^ string_of_int (nparams + i), T)) Ts;
   149         val params = map_index (fn (i, T) => Free ("par" ^ string_of_int (nparams + i), T)) Ts;
   152         val ts' = map_index (fn (i, t) => (subst_bounds (rev params, t), nfacts + i)) ts;
   150         val ts' = map_index (fn (i, t) => (subst_bounds (rev params, t), nfacts + i)) ts;
   153         val dom' =
   151         val dom' =
   154           fold (fn (T, p) => Typtab.map_default (T, []) (fn ps => ps @ [p])) (Ts ~~ params) dom;
   152           fold (fn (T, p) => Typtab.map_default (T, []) (fn ps => ps @ [p])) (Ts ~~ params) dom;
   155         val facts' = fold (fn (t, i) => Net.insert_term op = (t, (t, i))) ts' facts;
   153         val facts' = fold (fn (t, i) => Net.insert_term op = (t, (t, i))) ts' facts;
   163       end;
   161       end;
   164 
   162 
   165 
   163 
   166 (** proof replaying **)
   164 (** proof replaying **)
   167 
   165 
   168 fun thm_of_cl_prf thy goal asms (ClPrf (th, (tye, env), insts, is, prfs)) =
   166 fun thm_of_cl_prf ctxt goal asms (ClPrf (th, (tye, env), insts, is, prfs)) =
   169   let
   167   let
       
   168     val thy = Proof_Context.theory_of ctxt;
       
   169     val cert = Thm.cterm_of thy;
       
   170     val certT = Thm.ctyp_of thy;
   170     val _ =
   171     val _ =
   171       message (fn () =>
   172       cond_trace ctxt (fn () =>
   172         cat_lines ("asms:" :: map (Display.string_of_thm_global thy) asms) ^ "\n\n");
   173         cat_lines ("asms:" :: map (Display.string_of_thm ctxt) asms) ^ "\n\n");
   173     val th' =
   174     val th' =
   174       Drule.implies_elim_list
   175       Drule.implies_elim_list
   175         (Thm.instantiate
   176         (Thm.instantiate
   176            (map (fn (ixn, (S, T)) =>
   177            (map (fn (ixn, (S, T)) => (certT (TVar ((ixn, S))), certT T)) (Vartab.dest tye),
   177               (Thm.ctyp_of thy (TVar ((ixn, S))), Thm.ctyp_of thy T))
       
   178                  (Vartab.dest tye),
       
   179             map (fn (ixn, (T, t)) =>
   178             map (fn (ixn, (T, t)) =>
   180               (Thm.cterm_of thy (Var (ixn, Envir.subst_type tye T)),
   179               (cert (Var (ixn, Envir.subst_type tye T)), cert t)) (Vartab.dest env) @
   181                Thm.cterm_of thy t)) (Vartab.dest env) @
   180             map (fn (ixnT, t) => (cert (Var ixnT), cert t)) insts) th)
   182             map (fn (ixnT, t) =>
       
   183               (Thm.cterm_of thy (Var ixnT), Thm.cterm_of thy t)) insts) th)
       
   184         (map (nth asms) is);
   181         (map (nth asms) is);
   185     val (_, cases) = dest_elim (prop_of th');
   182     val (_, cases) = dest_elim (prop_of th');
   186   in
   183   in
   187     (case (cases, prfs) of
   184     (case (cases, prfs) of
   188       ([([], [_])], []) => th'
   185       ([([], [_])], []) => th'
   189     | ([([], [_])], [([], prf)]) => thm_of_cl_prf thy goal (asms @ [th']) prf
   186     | ([([], [_])], [([], prf)]) => thm_of_cl_prf ctxt goal (asms @ [th']) prf
   190     | _ =>
   187     | _ =>
   191         Drule.implies_elim_list
   188         Drule.implies_elim_list
   192           (Thm.instantiate (Thm.match
   189           (Thm.instantiate (Thm.match
   193              (Drule.strip_imp_concl (cprop_of th'), goal)) th')
   190              (Drule.strip_imp_concl (cprop_of th'), goal)) th')
   194           (map (thm_of_case_prf thy goal asms) (prfs ~~ cases)))
   191           (map (thm_of_case_prf ctxt goal asms) (prfs ~~ cases)))
   195   end
   192   end
   196 
   193 
   197 and thm_of_case_prf thy goal asms ((params, prf), (_, asms')) =
   194 and thm_of_case_prf ctxt goal asms ((params, prf), (_, asms')) =
   198   let
   195   let
   199     val cparams = map (cterm_of thy) params;
   196     val thy = Proof_Context.theory_of ctxt;
   200     val asms'' = map (cterm_of thy o curry subst_bounds (rev params)) asms';
   197     val cert = Thm.cterm_of thy;
       
   198     val cparams = map cert params;
       
   199     val asms'' = map (cert o curry subst_bounds (rev params)) asms';
   201   in
   200   in
   202     Drule.forall_intr_list cparams
   201     Drule.forall_intr_list cparams
   203       (Drule.implies_intr_list asms''
   202       (Drule.implies_intr_list asms''
   204         (thm_of_cl_prf thy goal (asms @ map Thm.assume asms'') prf))
   203         (thm_of_cl_prf ctxt goal (asms @ map Thm.assume asms'') prf))
   205   end;
   204   end;
   206 
   205 
   207 
   206 
   208 (** external interface **)
   207 (** external interface **)
   209 
   208 
   214       val xs =
   213       val xs =
   215         map (term_of o #2) params @
   214         map (term_of o #2) params @
   216         map (fn (_, s) => Free (s, the (Variable.default_type ctxt'' s)))
   215         map (fn (_, s) => Free (s, the (Variable.default_type ctxt'' s)))
   217           (rev (Variable.dest_fixes ctxt''))  (* FIXME !? *)
   216           (rev (Variable.dest_fixes ctxt''))  (* FIXME !? *)
   218     in
   217     in
   219       (case valid ctxt'' (map (mk_rule ctxt'') (prems' @ prems @ rules)) (term_of concl)
   218       (case
   220            (mk_dom xs) Net.empty 0 0 of
   219         valid ctxt'' (map (mk_rule ctxt'') (prems' @ prems @ rules)) (term_of concl)
       
   220           (mk_dom xs) Net.empty 0 0 of
   221         NONE => no_tac
   221         NONE => no_tac
   222       | SOME prf => rtac (thm_of_cl_prf (Proof_Context.theory_of ctxt'') concl [] prf) 1)
   222       | SOME prf => rtac (thm_of_cl_prf ctxt'' concl [] prf) 1)
   223     end) ctxt' 1) ctxt;
   223     end) ctxt' 1) ctxt;
   224 
   224 
   225 val setup = Method.setup @{binding coherent}
   225 val _ = Theory.setup
   226   (Attrib.thms >> (fn rules => fn ctxt =>
   226   (trace_setup #>
   227       METHOD (fn facts => HEADGOAL (coherent_tac ctxt (facts @ rules)))))
   227    Method.setup @{binding coherent}
   228     "prove coherent formula";
   228     (Attrib.thms >> (fn rules => fn ctxt =>
       
   229         METHOD (fn facts => HEADGOAL (coherent_tac ctxt (facts @ rules)))))
       
   230       "prove coherent formula");
   229 
   231 
   230 end;
   232 end;