src/HOL/Tools/Predicate_Compile/predicate_compile_proof.ML
changeset 55437 3fd63b92ea3b
parent 54742 7a86358a3c0b
child 55440 721b4561007a
equal deleted inserted replaced
55436:9781e17dcc23 55437:3fd63b92ea3b
    20 
    20 
    21 open Predicate_Compile_Aux;
    21 open Predicate_Compile_Aux;
    22 open Core_Data;
    22 open Core_Data;
    23 open Mode_Inference;
    23 open Mode_Inference;
    24 
    24 
       
    25 
    25 (* debug stuff *)
    26 (* debug stuff *)
    26 
    27 
    27 fun print_tac options s = 
    28 fun print_tac options s = 
    28   if show_proof_trace options then Tactical.print_tac s else Seq.single;
    29   if show_proof_trace options then Tactical.print_tac s else Seq.single;
    29 
    30 
       
    31 
    30 (** auxiliary **)
    32 (** auxiliary **)
    31 
    33 
    32 datatype assertion = Max_number_of_subgoals of int
    34 datatype assertion = Max_number_of_subgoals of int
       
    35 
    33 fun assert_tac (Max_number_of_subgoals i) st =
    36 fun assert_tac (Max_number_of_subgoals i) st =
    34   if (nprems_of st <= i) then Seq.single st
    37   if (nprems_of st <= i) then Seq.single st
    35   else raise Fail ("assert_tac: Numbers of subgoals mismatch at goal state :"
    38   else
    36     ^ "\n" ^ Pretty.string_of (Pretty.chunks
    39     raise Fail ("assert_tac: Numbers of subgoals mismatch at goal state :\n" ^
    37       (Goal_Display.pretty_goals_without_context st)));
    40       Pretty.string_of (Pretty.chunks
       
    41         (Goal_Display.pretty_goals_without_context st)))
    38 
    42 
    39 
    43 
    40 (** special setup for simpset **)
    44 (** special setup for simpset **)
       
    45 
    41 val HOL_basic_ss' =
    46 val HOL_basic_ss' =
    42   simpset_of (put_simpset HOL_basic_ss @{context}
    47   simpset_of (put_simpset HOL_basic_ss @{context}
    43     addsimps @{thms simp_thms Pair_eq}
    48     addsimps @{thms simp_thms Pair_eq}
    44     setSolver (mk_solver "all_tac_solver" (fn _ => fn _ => all_tac))
    49     setSolver (mk_solver "all_tac_solver" (fn _ => fn _ => all_tac))
    45     setSolver (mk_solver "True_solver" (fn _ => rtac @{thm TrueI})))
    50     setSolver (mk_solver "True_solver" (fn _ => rtac @{thm TrueI})))
    46 
    51 
       
    52 
    47 (* auxillary functions *)
    53 (* auxillary functions *)
    48 
    54 
    49 fun is_Type (Type _) = true
    55 fun is_Type (Type _) = true
    50   | is_Type _ = false
    56   | is_Type _ = false
    51 
    57 
    52 (* returns true if t is an application of an datatype constructor *)
    58 (* returns true if t is an application of an datatype constructor *)
    53 (* which then consequently would be splitted *)
    59 (* which then consequently would be splitted *)
    54 (* else false *)
    60 (* else false *)
    55 fun is_constructor thy t =
    61 fun is_constructor thy t =
    56   if (is_Type (fastype_of t)) then
    62   if is_Type (fastype_of t) then
    57     (case Datatype.get_info thy ((fst o dest_Type o fastype_of) t) of
    63     (case Datatype.get_info thy ((fst o dest_Type o fastype_of) t) of
    58       NONE => false
    64       NONE => false
    59     | SOME info => (let
    65     | SOME info =>
    60       val constr_consts = maps (fn (_, (_, _, constrs)) => map fst constrs) (#descr info)
    66         let
    61       val (c, _) = strip_comb t
    67           val constr_consts = maps (fn (_, (_, _, constrs)) => map fst constrs) (#descr info)
    62       in (case c of
    68           val (c, _) = strip_comb t
    63         Const (name, _) => member (op =) constr_consts name
    69         in
    64         | _ => false) end))
    70           (case c of
       
    71             Const (name, _) => member (op =) constr_consts name
       
    72           | _ => false)
       
    73         end)
    65   else false
    74   else false
    66 
    75 
    67 (* MAJOR FIXME:  prove_params should be simple
    76 (* MAJOR FIXME:  prove_params should be simple
    68  - different form of introrule for parameters ? *)
    77  - different form of introrule for parameters ? *)
    69 
    78 
    71   let
    80   let
    72     val  (f, args) = strip_comb (Envir.eta_contract t)
    81     val  (f, args) = strip_comb (Envir.eta_contract t)
    73     val mode = head_mode_of deriv
    82     val mode = head_mode_of deriv
    74     val param_derivations = param_derivations_of deriv
    83     val param_derivations = param_derivations_of deriv
    75     val ho_args = ho_args_of mode args
    84     val ho_args = ho_args_of mode args
    76     val f_tac = case f of
    85     val f_tac =
    77       Const (name, _) => simp_tac (put_simpset HOL_basic_ss ctxt addsimps
    86       (case f of
    78          [@{thm eval_pred}, predfun_definition_of ctxt name mode,
    87         Const (name, _) => simp_tac (put_simpset HOL_basic_ss ctxt addsimps
    79          @{thm split_eta}, @{thm split_beta}, @{thm fst_conv},
    88            [@{thm eval_pred}, predfun_definition_of ctxt name mode,
    80          @{thm snd_conv}, @{thm pair_collapse}, @{thm Product_Type.split_conv}]) 1
    89            @{thm split_eta}, @{thm split_beta}, @{thm fst_conv},
    81     | Free _ =>
    90            @{thm snd_conv}, @{thm pair_collapse}, @{thm Product_Type.split_conv}]) 1
    82       Subgoal.FOCUS_PREMS (fn {context = ctxt', params = params, prems, asms, concl, schematics} =>
    91       | Free _ =>
    83         let
    92         Subgoal.FOCUS_PREMS (fn {context = ctxt', params = params, prems, asms, concl, schematics} =>
    84           val prems' = maps dest_conjunct_prem (take nargs prems)
    93           let
    85         in
    94             val prems' = maps dest_conjunct_prem (take nargs prems)
    86           rewrite_goal_tac ctxt' (map (fn th => th RS @{thm sym} RS @{thm eq_reflection}) prems') 1
    95           in
    87         end) ctxt 1
    96             rewrite_goal_tac ctxt' (map (fn th => th RS @{thm sym} RS @{thm eq_reflection}) prems') 1
    88     | Abs _ => raise Fail "prove_param: No valid parameter term"
    97           end) ctxt 1
       
    98       | Abs _ => raise Fail "prove_param: No valid parameter term")
    89   in
    99   in
    90     REPEAT_DETERM (rtac @{thm ext} 1)
   100     REPEAT_DETERM (rtac @{thm ext} 1)
    91     THEN print_tac options "prove_param"
   101     THEN print_tac options "prove_param"
    92     THEN f_tac 
   102     THEN f_tac 
    93     THEN print_tac options "after prove_param"
   103     THEN print_tac options "after prove_param"
    95     THEN (EVERY (map2 (prove_param options ctxt nargs) ho_args param_derivations))
   105     THEN (EVERY (map2 (prove_param options ctxt nargs) ho_args param_derivations))
    96     THEN REPEAT_DETERM (rtac @{thm refl} 1)
   106     THEN REPEAT_DETERM (rtac @{thm refl} 1)
    97   end
   107   end
    98 
   108 
    99 fun prove_expr options ctxt nargs (premposition : int) (t, deriv) =
   109 fun prove_expr options ctxt nargs (premposition : int) (t, deriv) =
   100   case strip_comb t of
   110   (case strip_comb t of
   101     (Const (name, _), args) =>
   111     (Const (name, _), args) =>
   102       let
   112       let
   103         val mode = head_mode_of deriv
   113         val mode = head_mode_of deriv
   104         val introrule = predfun_intro_of ctxt name mode
   114         val introrule = predfun_intro_of ctxt name mode
   105         val param_derivations = param_derivations_of deriv
   115         val param_derivations = param_derivations_of deriv
   115         (* work with parameter arguments *)
   125         (* work with parameter arguments *)
   116         THEN (EVERY (map2 (prove_param options ctxt nargs) ho_args param_derivations))
   126         THEN (EVERY (map2 (prove_param options ctxt nargs) ho_args param_derivations))
   117         THEN (REPEAT_DETERM (atac 1))
   127         THEN (REPEAT_DETERM (atac 1))
   118       end
   128       end
   119   | (Free _, _) =>
   129   | (Free _, _) =>
   120     print_tac options "proving parameter call.."
   130       print_tac options "proving parameter call.."
   121     THEN Subgoal.FOCUS_PREMS (fn {context = ctxt', params, prems, asms, concl, schematics} =>
   131       THEN Subgoal.FOCUS_PREMS (fn {context = ctxt', params, prems, asms, concl, schematics} =>
   122         let
   132           let
   123           val param_prem = nth prems premposition
   133             val param_prem = nth prems premposition
   124           val (param, _) = strip_comb (HOLogic.dest_Trueprop (prop_of param_prem))
   134             val (param, _) = strip_comb (HOLogic.dest_Trueprop (prop_of param_prem))
   125           val prems' = maps dest_conjunct_prem (take nargs prems)
   135             val prems' = maps dest_conjunct_prem (take nargs prems)
   126           fun param_rewrite prem =
   136             fun param_rewrite prem =
   127             param = snd (HOLogic.dest_eq (HOLogic.dest_Trueprop (prop_of prem)))
   137               param = snd (HOLogic.dest_eq (HOLogic.dest_Trueprop (prop_of prem)))
   128           val SOME rew_eq = find_first param_rewrite prems'
   138             val SOME rew_eq = find_first param_rewrite prems'
   129           val param_prem' = rewrite_rule ctxt'
   139             val param_prem' = rewrite_rule ctxt'
   130             (map (fn th => th RS @{thm eq_reflection})
   140               (map (fn th => th RS @{thm eq_reflection})
   131               [rew_eq RS @{thm sym}, @{thm split_beta}, @{thm fst_conv}, @{thm snd_conv}])
   141                 [rew_eq RS @{thm sym}, @{thm split_beta}, @{thm fst_conv}, @{thm snd_conv}])
   132             param_prem
   142               param_prem
   133         in
   143           in
   134           rtac param_prem' 1
   144             rtac param_prem' 1
   135         end) ctxt 1
   145           end) ctxt 1
   136     THEN print_tac options "after prove parameter call"
   146       THEN print_tac options "after prove parameter call")
   137 
   147 
   138 fun SOLVED tac st = FILTER (fn st' => nprems_of st' = nprems_of st - 1) tac st;
   148 fun SOLVED tac st = FILTER (fn st' => nprems_of st' = nprems_of st - 1) tac st
   139 
   149 
   140 fun prove_match options ctxt nargs out_ts =
   150 fun prove_match options ctxt nargs out_ts =
   141   let
   151   let
   142     val thy = Proof_Context.theory_of ctxt
   152     val thy = Proof_Context.theory_of ctxt
   143     val eval_if_P =
   153     val eval_if_P =
   152       else []
   162       else []
   153     val simprules = insert Thm.eq_thm @{thm "unit.cases"} (insert Thm.eq_thm @{thm "prod.cases"}
   163     val simprules = insert Thm.eq_thm @{thm "unit.cases"} (insert Thm.eq_thm @{thm "prod.cases"}
   154       (fold (union Thm.eq_thm) (map get_case_rewrite out_ts) []))
   164       (fold (union Thm.eq_thm) (map get_case_rewrite out_ts) []))
   155   (* replace TRY by determining if it necessary - are there equations when calling compile match? *)
   165   (* replace TRY by determining if it necessary - are there equations when calling compile match? *)
   156   in
   166   in
   157      (* make this simpset better! *)
   167     (* make this simpset better! *)
   158     asm_full_simp_tac (put_simpset HOL_basic_ss' ctxt addsimps simprules) 1
   168     asm_full_simp_tac (put_simpset HOL_basic_ss' ctxt addsimps simprules) 1
   159     THEN print_tac options "after prove_match:"
   169     THEN print_tac options "after prove_match:"
   160     THEN (DETERM (TRY 
   170     THEN (DETERM (TRY 
   161            (rtac eval_if_P 1
   171            (rtac eval_if_P 1
   162            THEN (SUBPROOF (fn {context, params, prems, asms, concl, schematics} =>
   172            THEN (SUBPROOF (fn {context, params, prems, asms, concl, schematics} =>
   174              THEN REPEAT_DETERM (rtac @{thm refl} 1))
   184              THEN REPEAT_DETERM (rtac @{thm refl} 1))
   175              THEN print_tac options "after if simp; in SUBPROOF") ctxt 1))))
   185              THEN print_tac options "after if simp; in SUBPROOF") ctxt 1))))
   176     THEN print_tac options "after if simplification"
   186     THEN print_tac options "after if simplification"
   177   end;
   187   end;
   178 
   188 
       
   189 
   179 (* corresponds to compile_fun -- maybe call that also compile_sidecond? *)
   190 (* corresponds to compile_fun -- maybe call that also compile_sidecond? *)
   180 
   191 
   181 fun prove_sidecond ctxt t =
   192 fun prove_sidecond ctxt t =
   182   let
   193   let
   183     fun preds_of t nameTs = case strip_comb t of 
   194     fun preds_of t nameTs =
   184       (Const (name, T), args) =>
   195       (case strip_comb t of
   185         if is_registered ctxt name then (name, T) :: nameTs
   196         (Const (name, T), args) =>
   186           else fold preds_of args nameTs
   197           if is_registered ctxt name then (name, T) :: nameTs
   187       | _ => nameTs
   198             else fold preds_of args nameTs
       
   199       | _ => nameTs)
   188     val preds = preds_of t []
   200     val preds = preds_of t []
   189     val defs = map
   201     val defs = map
   190       (fn (pred, T) => predfun_definition_of ctxt pred
   202       (fn (pred, T) => predfun_definition_of ctxt pred
   191         (all_input_of T))
   203         (all_input_of T))
   192         preds
   204         preds
   198 
   210 
   199 fun prove_clause options ctxt nargs mode (_, clauses) (ts, moded_ps) =
   211 fun prove_clause options ctxt nargs mode (_, clauses) (ts, moded_ps) =
   200   let
   212   let
   201     val (in_ts, clause_out_ts) = split_mode mode ts;
   213     val (in_ts, clause_out_ts) = split_mode mode ts;
   202     fun prove_prems out_ts [] =
   214     fun prove_prems out_ts [] =
   203       (prove_match options ctxt nargs out_ts)
   215         (prove_match options ctxt nargs out_ts)
   204       THEN print_tac options "before simplifying assumptions"
   216         THEN print_tac options "before simplifying assumptions"
   205       THEN asm_full_simp_tac (put_simpset HOL_basic_ss' ctxt) 1
   217         THEN asm_full_simp_tac (put_simpset HOL_basic_ss' ctxt) 1
   206       THEN print_tac options "before single intro rule"
   218         THEN print_tac options "before single intro rule"
   207       THEN Subgoal.FOCUS_PREMS
   219         THEN Subgoal.FOCUS_PREMS
   208          (fn {context = ctxt', params, prems, asms, concl, schematics} =>
   220            (fn {context = ctxt', params, prems, asms, concl, schematics} =>
   209           let
   221             let
   210             val prems' = maps dest_conjunct_prem (take nargs prems)
   222               val prems' = maps dest_conjunct_prem (take nargs prems)
   211           in
   223             in
   212             rewrite_goal_tac ctxt' (map (fn th => th RS @{thm sym} RS @{thm eq_reflection}) prems') 1
   224               rewrite_goal_tac ctxt' (map (fn th => th RS @{thm sym} RS @{thm eq_reflection}) prems') 1
   213           end) ctxt 1
   225             end) ctxt 1
   214       THEN (rtac (if null clause_out_ts then @{thm singleI_unit} else @{thm singleI}) 1)
   226         THEN (rtac (if null clause_out_ts then @{thm singleI_unit} else @{thm singleI}) 1)
   215     | prove_prems out_ts ((p, deriv) :: ps) =
   227     | prove_prems out_ts ((p, deriv) :: ps) =
   216       let
   228         let
   217         val premposition = (find_index (equal p) clauses) + nargs
   229           val premposition = (find_index (equal p) clauses) + nargs
   218         val mode = head_mode_of deriv
   230           val mode = head_mode_of deriv
   219         val rest_tac =
   231           val rest_tac =
   220           rtac @{thm bindI} 1
   232             rtac @{thm bindI} 1
   221           THEN (case p of Prem t =>
   233             THEN (case p of Prem t =>
   222             let
   234               let
   223               val (_, us) = strip_comb t
   235                 val (_, us) = strip_comb t
   224               val (_, out_ts''') = split_mode mode us
   236                 val (_, out_ts''') = split_mode mode us
   225               val rec_tac = prove_prems out_ts''' ps
   237                 val rec_tac = prove_prems out_ts''' ps
   226             in
   238               in
   227               print_tac options "before clause:"
   239                 print_tac options "before clause:"
   228               (*THEN asm_simp_tac (put_simpset HOL_basic_ss ctxt) 1*)
   240                 (*THEN asm_simp_tac (put_simpset HOL_basic_ss ctxt) 1*)
   229               THEN print_tac options "before prove_expr:"
   241                 THEN print_tac options "before prove_expr:"
   230               THEN prove_expr options ctxt nargs premposition (t, deriv)
   242                 THEN prove_expr options ctxt nargs premposition (t, deriv)
   231               THEN print_tac options "after prove_expr:"
   243                 THEN print_tac options "after prove_expr:"
   232               THEN rec_tac
   244                 THEN rec_tac
   233             end
   245               end
   234           | Negprem t =>
   246             | Negprem t =>
   235             let
   247               let
   236               val (t, args) = strip_comb t
   248                 val (t, args) = strip_comb t
   237               val (_, out_ts''') = split_mode mode args
   249                 val (_, out_ts''') = split_mode mode args
   238               val rec_tac = prove_prems out_ts''' ps
   250                 val rec_tac = prove_prems out_ts''' ps
   239               val name = (case strip_comb t of (Const (c, _), _) => SOME c | _ => NONE)
   251                 val name = (case strip_comb t of (Const (c, _), _) => SOME c | _ => NONE)
   240               val neg_intro_rule =
   252                 val neg_intro_rule =
   241                 Option.map (fn name =>
   253                   Option.map (fn name =>
   242                   the (predfun_neg_intro_of ctxt name mode)) name
   254                     the (predfun_neg_intro_of ctxt name mode)) name
   243               val param_derivations = param_derivations_of deriv
   255                 val param_derivations = param_derivations_of deriv
   244               val params = ho_args_of mode args
   256                 val params = ho_args_of mode args
   245             in
   257               in
   246               print_tac options "before prove_neg_expr:"
   258                 print_tac options "before prove_neg_expr:"
   247               THEN full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps
   259                 THEN full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps
   248                 [@{thm split_eta}, @{thm split_beta}, @{thm fst_conv},
   260                   [@{thm split_eta}, @{thm split_beta}, @{thm fst_conv},
   249                  @{thm snd_conv}, @{thm pair_collapse}, @{thm Product_Type.split_conv}]) 1
   261                    @{thm snd_conv}, @{thm pair_collapse}, @{thm Product_Type.split_conv}]) 1
   250               THEN (if (is_some name) then
   262                 THEN (if (is_some name) then
   251                   print_tac options "before applying not introduction rule"
   263                     print_tac options "before applying not introduction rule"
   252                   THEN Subgoal.FOCUS_PREMS
   264                     THEN Subgoal.FOCUS_PREMS
   253                     (fn {context, params = params, prems, asms, concl, schematics} =>
   265                       (fn {context, params = params, prems, asms, concl, schematics} =>
   254                       rtac (the neg_intro_rule) 1
   266                         rtac (the neg_intro_rule) 1
   255                       THEN rtac (nth prems premposition) 1) ctxt 1
   267                         THEN rtac (nth prems premposition) 1) ctxt 1
   256                   THEN print_tac options "after applying not introduction rule"
   268                     THEN print_tac options "after applying not introduction rule"
   257                   THEN (EVERY (map2 (prove_param options ctxt nargs) params param_derivations))
   269                     THEN (EVERY (map2 (prove_param options ctxt nargs) params param_derivations))
   258                   THEN (REPEAT_DETERM (atac 1))
   270                     THEN (REPEAT_DETERM (atac 1))
   259                 else
   271                   else
   260                   rtac @{thm not_predI'} 1
   272                     rtac @{thm not_predI'} 1
   261                   (* test: *)
   273                     (* test: *)
   262                   THEN dtac @{thm sym} 1
   274                     THEN dtac @{thm sym} 1
   263                   THEN asm_full_simp_tac
   275                     THEN asm_full_simp_tac
   264                     (put_simpset HOL_basic_ss ctxt addsimps [@{thm not_False_eq_True}]) 1)
   276                       (put_simpset HOL_basic_ss ctxt addsimps [@{thm not_False_eq_True}]) 1)
   265                   THEN simp_tac
   277                     THEN simp_tac
   266                     (put_simpset HOL_basic_ss ctxt addsimps [@{thm not_False_eq_True}]) 1
   278                       (put_simpset HOL_basic_ss ctxt addsimps [@{thm not_False_eq_True}]) 1
   267               THEN rec_tac
   279                 THEN rec_tac
   268             end
   280               end
   269           | Sidecond t =>
   281             | Sidecond t =>
   270            rtac @{thm if_predI} 1
   282              rtac @{thm if_predI} 1
   271            THEN print_tac options "before sidecond:"
   283              THEN print_tac options "before sidecond:"
   272            THEN prove_sidecond ctxt t
   284              THEN prove_sidecond ctxt t
   273            THEN print_tac options "after sidecond:"
   285              THEN print_tac options "after sidecond:"
   274            THEN prove_prems [] ps)
   286              THEN prove_prems [] ps)
   275       in (prove_match options ctxt nargs out_ts)
   287         in (prove_match options ctxt nargs out_ts)
   276           THEN rest_tac
   288             THEN rest_tac
   277       end;
   289         end
   278     val prems_tac = prove_prems in_ts moded_ps
   290     val prems_tac = prove_prems in_ts moded_ps
   279   in
   291   in
   280     print_tac options "Proving clause..."
   292     print_tac options "Proving clause..."
   281     THEN rtac @{thm bindI} 1
   293     THEN rtac @{thm bindI} 1
   282     THEN rtac @{thm singleI} 1
   294     THEN rtac @{thm singleI} 1
   283     THEN prems_tac
   295     THEN prems_tac
   284   end;
   296   end
   285 
   297 
   286 fun select_sup 1 1 = []
   298 fun select_sup 1 1 = []
   287   | select_sup _ 1 = [rtac @{thm supI1}]
   299   | select_sup _ 1 = [rtac @{thm supI1}]
   288   | select_sup n i = (rtac @{thm supI2})::(select_sup (n - 1) (i - 1));
   300   | select_sup n i = (rtac @{thm supI2})::(select_sup (n - 1) (i - 1));
   289 
   301 
   301     THEN (EVERY (map
   313     THEN (EVERY (map
   302            (fn i => EVERY' (select_sup (length moded_clauses) i) i) 
   314            (fn i => EVERY' (select_sup (length moded_clauses) i) i) 
   303              (1 upto (length moded_clauses))))
   315              (1 upto (length moded_clauses))))
   304     THEN (EVERY (map2 (prove_clause options ctxt nargs mode) clauses moded_clauses))
   316     THEN (EVERY (map2 (prove_clause options ctxt nargs mode) clauses moded_clauses))
   305     THEN print_tac options "proved one direction"
   317     THEN print_tac options "proved one direction"
   306   end;
   318   end
       
   319 
   307 
   320 
   308 (** Proof in the other direction **)
   321 (** Proof in the other direction **)
   309 
   322 
   310 fun prove_match2 options ctxt out_ts =
   323 fun prove_match2 options ctxt out_ts =
   311   let
   324   let
   346   let
   359   let
   347     val (f, args) = strip_comb (Envir.eta_contract t)
   360     val (f, args) = strip_comb (Envir.eta_contract t)
   348     val mode = head_mode_of deriv
   361     val mode = head_mode_of deriv
   349     val param_derivations = param_derivations_of deriv
   362     val param_derivations = param_derivations_of deriv
   350     val ho_args = ho_args_of mode args
   363     val ho_args = ho_args_of mode args
   351     val f_tac = case f of
   364     val f_tac =
       
   365       (case f of
   352         Const (name, _) => full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps 
   366         Const (name, _) => full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps 
   353            (@{thm eval_pred}::(predfun_definition_of ctxt name mode)
   367            (@{thm eval_pred}::(predfun_definition_of ctxt name mode)
   354            :: @{thm "Product_Type.split_conv"}::[])) 1
   368            :: @{thm "Product_Type.split_conv"}::[])) 1
   355       | Free _ => all_tac
   369       | Free _ => all_tac
   356       | _ => error "prove_param2: illegal parameter term"
   370       | _ => error "prove_param2: illegal parameter term")
   357   in
   371   in
   358     print_tac options "before simplification in prove_args:"
   372     print_tac options "before simplification in prove_args:"
   359     THEN f_tac
   373     THEN f_tac
   360     THEN print_tac options "after simplification in prove_args"
   374     THEN print_tac options "after simplification in prove_args"
   361     THEN EVERY (map2 (prove_param2 options ctxt) ho_args param_derivations)
   375     THEN EVERY (map2 (prove_param2 options ctxt) ho_args param_derivations)
   377           THEN (EVERY (map2 (prove_param2 options ctxt) ho_args param_derivations))
   391           THEN (EVERY (map2 (prove_param2 options ctxt) ho_args param_derivations))
   378           THEN print_tac options "finished prove_expr2"
   392           THEN print_tac options "finished prove_expr2"
   379         end
   393         end
   380       | _ => etac @{thm bindE} 1)
   394       | _ => etac @{thm bindE} 1)
   381 
   395 
   382 fun prove_sidecond2 options ctxt t = let
   396 fun prove_sidecond2 options ctxt t =
   383   fun preds_of t nameTs = case strip_comb t of 
   397   let
   384     (Const (name, T), args) =>
   398     fun preds_of t nameTs =
   385       if is_registered ctxt name then (name, T) :: nameTs
   399       (case strip_comb t of
   386         else fold preds_of args nameTs
   400         (Const (name, T), args) =>
   387     | _ => nameTs
   401           if is_registered ctxt name then (name, T) :: nameTs
   388   val preds = preds_of t []
   402             else fold preds_of args nameTs
   389   val defs = map
   403       | _ => nameTs)
   390     (fn (pred, T) => predfun_definition_of ctxt pred 
   404     val preds = preds_of t []
   391       (all_input_of T))
   405     val defs = map
   392       preds
   406       (fn (pred, T) => predfun_definition_of ctxt pred 
   393   in
   407         (all_input_of T))
   394    (* only simplify the one assumption *)
   408         preds
   395    full_simp_tac (put_simpset HOL_basic_ss' ctxt addsimps @{thm eval_pred} :: defs) 1 
   409   in
   396    (* need better control here! *)
   410     (* only simplify the one assumption *)
   397    THEN print_tac options "after sidecond2 simplification"
   411     full_simp_tac (put_simpset HOL_basic_ss' ctxt addsimps @{thm eval_pred} :: defs) 1 
   398    end
   412     (* need better control here! *)
       
   413     THEN print_tac options "after sidecond2 simplification"
       
   414   end
   399   
   415   
   400 fun prove_clause2 options ctxt pred mode (ts, ps) i =
   416 fun prove_clause2 options ctxt pred mode (ts, ps) i =
   401   let
   417   let
   402     val pred_intro_rule = nth (intros_of ctxt pred) (i - 1)
   418     val pred_intro_rule = nth (intros_of ctxt pred) (i - 1)
   403     val (in_ts, _) = split_mode mode ts;
   419     val (in_ts, _) = split_mode mode ts;
   424           THEN' (K (print_tac options "state after pre-simplification:"))
   440           THEN' (K (print_tac options "state after pre-simplification:"))
   425         THEN' (K (print_tac options "state after assumption matching:")))) 1))
   441         THEN' (K (print_tac options "state after assumption matching:")))) 1))
   426     | prove_prems2 out_ts ((p, deriv) :: ps) =
   442     | prove_prems2 out_ts ((p, deriv) :: ps) =
   427       let
   443       let
   428         val mode = head_mode_of deriv
   444         val mode = head_mode_of deriv
   429         val rest_tac = (case p of
   445         val rest_tac =
   430           Prem t =>
   446           (case p of
   431           let
   447             Prem t =>
   432             val (_, us) = strip_comb t
   448               let
   433             val (_, out_ts''') = split_mode mode us
   449                 val (_, us) = strip_comb t
   434             val rec_tac = prove_prems2 out_ts''' ps
   450                 val (_, out_ts''') = split_mode mode us
   435           in
   451                 val rec_tac = prove_prems2 out_ts''' ps
   436             (prove_expr2 options ctxt (t, deriv)) THEN rec_tac
   452               in
   437           end
   453                 (prove_expr2 options ctxt (t, deriv)) THEN rec_tac
   438         | Negprem t =>
   454               end
   439           let
   455           | Negprem t =>
   440             val (_, args) = strip_comb t
   456               let
   441             val (_, out_ts''') = split_mode mode args
   457                 val (_, args) = strip_comb t
   442             val rec_tac = prove_prems2 out_ts''' ps
   458                 val (_, out_ts''') = split_mode mode args
   443             val name = (case strip_comb t of (Const (c, _), _) => SOME c | _ => NONE)
   459                 val rec_tac = prove_prems2 out_ts''' ps
   444             val param_derivations = param_derivations_of deriv
   460                 val name = (case strip_comb t of (Const (c, _), _) => SOME c | _ => NONE)
   445             val ho_args = ho_args_of mode args
   461                 val param_derivations = param_derivations_of deriv
   446           in
   462                 val ho_args = ho_args_of mode args
   447             print_tac options "before neg prem 2"
   463               in
   448             THEN etac @{thm bindE} 1
   464                 print_tac options "before neg prem 2"
   449             THEN (if is_some name then
   465                 THEN etac @{thm bindE} 1
   450                 full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps
   466                 THEN (if is_some name then
   451                   [predfun_definition_of ctxt (the name) mode]) 1
   467                     full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps
   452                 THEN etac @{thm not_predE} 1
   468                       [predfun_definition_of ctxt (the name) mode]) 1
   453                 THEN simp_tac (put_simpset HOL_basic_ss ctxt addsimps [@{thm not_False_eq_True}]) 1
   469                     THEN etac @{thm not_predE} 1
   454                 THEN (EVERY (map2 (prove_param2 options ctxt) ho_args param_derivations))
   470                     THEN simp_tac (put_simpset HOL_basic_ss ctxt addsimps [@{thm not_False_eq_True}]) 1
   455               else
   471                     THEN (EVERY (map2 (prove_param2 options ctxt) ho_args param_derivations))
   456                 etac @{thm not_predE'} 1)
   472                   else
   457             THEN rec_tac
   473                     etac @{thm not_predE'} 1)
   458           end 
   474                 THEN rec_tac
   459         | Sidecond t =>
   475               end 
   460           etac @{thm bindE} 1
   476           | Sidecond t =>
   461           THEN etac @{thm if_predE} 1
   477               etac @{thm bindE} 1
   462           THEN prove_sidecond2 options ctxt t
   478               THEN etac @{thm if_predE} 1
   463           THEN prove_prems2 [] ps)
   479               THEN prove_sidecond2 options ctxt t
   464       in print_tac options "before prove_match2:"
   480               THEN prove_prems2 [] ps)
   465          THEN prove_match2 options ctxt out_ts
   481       in
   466          THEN print_tac options "after prove_match2:"
   482         print_tac options "before prove_match2:"
   467          THEN rest_tac
   483         THEN prove_match2 options ctxt out_ts
   468       end;
   484         THEN print_tac options "after prove_match2:"
       
   485         THEN rest_tac
       
   486       end
   469     val prems_tac = prove_prems2 in_ts ps 
   487     val prems_tac = prove_prems2 in_ts ps 
   470   in
   488   in
   471     print_tac options "starting prove_clause2"
   489     print_tac options "starting prove_clause2"
   472     THEN etac @{thm bindE} 1
   490     THEN etac @{thm bindE} 1
   473     THEN (etac @{thm singleE'} 1)
   491     THEN (etac @{thm singleE'} 1)
   487      THEN (rtac (predfun_intro_of ctxt pred mode) 1)
   505      THEN (rtac (predfun_intro_of ctxt pred mode) 1)
   488      THEN (REPEAT_DETERM (rtac @{thm refl} 2))
   506      THEN (REPEAT_DETERM (rtac @{thm refl} 2))
   489      THEN (
   507      THEN (
   490        if null moded_clauses then etac @{thm botE} 1
   508        if null moded_clauses then etac @{thm botE} 1
   491        else EVERY (map2 prove_clause moded_clauses (1 upto (length moded_clauses))))
   509        else EVERY (map2 prove_clause moded_clauses (1 upto (length moded_clauses))))
   492   end;
   510   end
       
   511 
   493 
   512 
   494 (** proof procedure **)
   513 (** proof procedure **)
   495 
   514 
   496 fun prove_pred options thy clauses preds pred (_, mode) (moded_clauses, compiled_term) =
   515 fun prove_pred options thy clauses preds pred (_, mode) (moded_clauses, compiled_term) =
   497   let
   516   let
   498     val ctxt = Proof_Context.init_global thy   (* FIXME proper context!? *)
   517     val ctxt = Proof_Context.init_global thy   (* FIXME proper context!? *)
   499     val clauses = case AList.lookup (op =) clauses pred of SOME rs => rs | NONE => []
   518     val clauses = (case AList.lookup (op =) clauses pred of SOME rs => rs | NONE => [])
   500   in
   519   in
   501     Goal.prove ctxt (Term.add_free_names compiled_term []) [] compiled_term
   520     Goal.prove ctxt (Term.add_free_names compiled_term []) [] compiled_term
   502       (if not (skip_proof options) then
   521       (if not (skip_proof options) then
   503         (fn _ =>
   522         (fn _ =>
   504         rtac @{thm pred_iffI} 1
   523         rtac @{thm pred_iffI} 1
   506         THEN prove_one_direction options ctxt clauses preds pred mode moded_clauses
   525         THEN prove_one_direction options ctxt clauses preds pred mode moded_clauses
   507         THEN print_tac options "proved one direction"
   526         THEN print_tac options "proved one direction"
   508         THEN prove_other_direction options ctxt pred mode moded_clauses
   527         THEN prove_other_direction options ctxt pred mode moded_clauses
   509         THEN print_tac options "proved other direction")
   528         THEN print_tac options "proved other direction")
   510       else (fn _ => ALLGOALS Skip_Proof.cheat_tac))
   529       else (fn _ => ALLGOALS Skip_Proof.cheat_tac))
   511   end;
   530   end
   512 
   531 
   513 end;
   532 end