src/HOL/Tools/Sledgehammer/sledgehammer_isar_proof.ML
changeset 72584 4ea19e5dc67e
parent 72583 e728d3a3d383
child 72585 18eb7ec2720f
equal deleted inserted replaced
72583:e728d3a3d383 72584:4ea19e5dc67e
    20       fixes : (string * typ) list,
    20       fixes : (string * typ) list,
    21       assumptions: (label * term) list,
    21       assumptions: (label * term) list,
    22       steps : isar_step list
    22       steps : isar_step list
    23     }
    23     }
    24   and isar_step =
    24   and isar_step =
    25     Let of term * term |
    25     Let of {
    26     Prove of isar_qualifier list * (string * typ) list * label * term * isar_proof list
    26       lhs : term,
    27       * facts * proof_method list * string
    27       rhs : term
       
    28     } |
       
    29     Prove of {
       
    30       qualifiers : isar_qualifier list,
       
    31       obtains : (string * typ) list,
       
    32       label : label,
       
    33       goal : term,
       
    34       subproofs : isar_proof list,
       
    35       facts : facts,
       
    36       proof_methods : proof_method list,
       
    37       comment : string
       
    38     }
    28 
    39 
    29   val no_label : label
    40   val no_label : label
    30 
    41 
    31   val label_ord : label ord
    42   val label_ord : label ord
    32   val string_of_label : label -> string
    43   val string_of_label : label -> string
    33   val sort_facts : facts -> facts
    44   val sort_facts : facts -> facts
    34 
    45 
    35   val steps_of_isar_proof : isar_proof -> isar_step list
    46   val steps_of_isar_proof : isar_proof -> isar_step list
    36   val isar_proof_with_steps : isar_proof -> isar_step list -> isar_proof
    47   val isar_proof_with_steps : isar_proof -> isar_step list -> isar_proof
       
    48 
    37   val label_of_isar_step : isar_step -> label option
    49   val label_of_isar_step : isar_step -> label option
    38   val facts_of_isar_step : isar_step -> facts
    50   val facts_of_isar_step : isar_step -> facts
    39   val proof_methods_of_isar_step : isar_step -> proof_method list
    51   val proof_methods_of_isar_step : isar_step -> proof_method list
    40 
    52 
    41   val fold_isar_steps : (isar_step -> 'a -> 'a) -> isar_step list -> 'a -> 'a
    53   val fold_isar_steps : (isar_step -> 'a -> 'a) -> isar_step list -> 'a -> 'a
    77     fixes : (string * typ) list,
    89     fixes : (string * typ) list,
    78     assumptions: (label * term) list,
    90     assumptions: (label * term) list,
    79     steps : isar_step list
    91     steps : isar_step list
    80   }
    92   }
    81 and isar_step =
    93 and isar_step =
    82   Let of term * term |
    94   Let of {
    83   Prove of isar_qualifier list * (string * typ) list * label * term * isar_proof list
    95     lhs : term,
    84     * facts * proof_method list * string
    96     rhs : term
       
    97   } |
       
    98   Prove of {
       
    99     qualifiers : isar_qualifier list,
       
   100     obtains : (string * typ) list,
       
   101     label : label,
       
   102     goal : term,
       
   103     subproofs : isar_proof list,
       
   104     facts : facts,
       
   105     proof_methods : proof_method list,
       
   106     comment : string
       
   107   }
    85 
   108 
    86 val no_label = ("", ~1)
   109 val no_label = ("", ~1)
    87 
   110 
    88 (* cf. "label_ord" below *)
   111 (* cf. "label_ord" below *)
    89 val assume_prefix = "a"
   112 val assume_prefix = "a"
   105 
   128 
   106 fun steps_of_isar_proof (Proof {steps, ...}) = steps
   129 fun steps_of_isar_proof (Proof {steps, ...}) = steps
   107 fun isar_proof_with_steps (Proof {fixes, assumptions, ...}) steps =
   130 fun isar_proof_with_steps (Proof {fixes, assumptions, ...}) steps =
   108   Proof {fixes = fixes, assumptions = assumptions, steps = steps}
   131   Proof {fixes = fixes, assumptions = assumptions, steps = steps}
   109 
   132 
   110 fun label_of_isar_step (Prove (_, _, l, _, _, _, _, _)) = SOME l
   133 fun label_of_isar_step (Prove {label, ...}) = SOME label
   111   | label_of_isar_step _ = NONE
   134   | label_of_isar_step _ = NONE
   112 
   135 
   113 fun subproofs_of_isar_step (Prove (_, _, _, _, subs, _, _, _)) = subs
   136 fun subproofs_of_isar_step (Prove {subproofs, ...}) = subproofs
   114   | subproofs_of_isar_step _ = []
   137   | subproofs_of_isar_step _ = []
   115 
   138 
   116 fun facts_of_isar_step (Prove (_, _, _, _, _, facts, _, _)) = facts
   139 fun facts_of_isar_step (Prove {facts, ...}) = facts
   117   | facts_of_isar_step _ = ([], [])
   140   | facts_of_isar_step _ = ([], [])
   118 
   141 
   119 fun proof_methods_of_isar_step (Prove (_, _, _, _, _, _, meths, _)) = meths
   142 fun proof_methods_of_isar_step (Prove {proof_methods, ...}) = proof_methods
   120   | proof_methods_of_isar_step _ = []
   143   | proof_methods_of_isar_step _ = []
   121 
   144 
   122 fun fold_isar_step f step =
   145 fun fold_isar_step f step =
   123   fold (steps_of_isar_proof #> fold_isar_steps f) (subproofs_of_isar_step step) #> f step
   146   fold (steps_of_isar_proof #> fold_isar_steps f) (subproofs_of_isar_step step) #> f step
   124 and fold_isar_steps f = fold (fold_isar_step f)
   147 and fold_isar_steps f = fold (fold_isar_step f)
   125 
   148 
   126 fun map_isar_steps f =
   149 fun map_isar_steps f =
   127   let
   150   let
   128     fun map_proof (proof as Proof {steps, ...}) = isar_proof_with_steps proof (map map_step steps)
   151     fun map_proof (proof as Proof {steps, ...}) = isar_proof_with_steps proof (map map_step steps)
   129     and map_step (step as Let _) = f step
   152     and map_step (step as Let _) = f step
   130       | map_step (Prove (qs, xs, l, t, subs, facts, meths, comment)) =
   153       | map_step (Prove {qualifiers, obtains, label, goal, subproofs, facts, proof_methods,
   131         f (Prove (qs, xs, l, t, map map_proof subs, facts, meths, comment))
   154           comment}) =
       
   155         f (Prove {
       
   156             qualifiers = qualifiers,
       
   157             obtains = obtains,
       
   158             label = label,
       
   159             goal = goal,
       
   160             subproofs = map map_proof subproofs,
       
   161             facts = facts,
       
   162             proof_methods = proof_methods,
       
   163             comment = comment})
   132   in map_proof end
   164   in map_proof end
   133 
   165 
   134 val add_isar_steps = fold_isar_steps (fn Prove _ => Integer.add 1 | _ => I)
   166 val add_isar_steps = fold_isar_steps (fn Prove _ => Integer.add 1 | _ => I)
   135 
   167 
   136 (* canonical proof labels: 1, 2, 3, ... in post traversal order *)
   168 (* canonical proof labels: 1, 2, 3, ... in post traversal order *)
   138 
   170 
   139 structure Canonical_Label_Tab = Table(
   171 structure Canonical_Label_Tab = Table(
   140   type key = label
   172   type key = label
   141   val ord = canonical_label_ord)
   173   val ord = canonical_label_ord)
   142 
   174 
   143 fun comment_isar_step comment_of (Prove (qs, xs, l, t, subs, facts, meths, _)) =
   175 fun comment_isar_step comment_of (Prove {qualifiers, obtains, label, goal, subproofs, facts,
   144     Prove (qs, xs, l, t, subs, facts, meths, comment_of l meths)
   176       proof_methods, ...}) =
       
   177     Prove {
       
   178       qualifiers = qualifiers,
       
   179       obtains = obtains,
       
   180       label = label,
       
   181       goal = goal,
       
   182       subproofs = subproofs,
       
   183       facts = facts,
       
   184       proof_methods = proof_methods,
       
   185       comment = comment_of label proof_methods}
   145   | comment_isar_step _ step = step
   186   | comment_isar_step _ step = step
   146 fun comment_isar_proof comment_of = map_isar_steps (comment_isar_step comment_of)
   187 fun comment_isar_proof comment_of = map_isar_steps (comment_isar_step comment_of)
   147 
   188 
   148 fun chain_qs_lfs NONE lfs = ([], lfs)
   189 fun chain_qs_lfs NONE lfs = ([], lfs)
   149   | chain_qs_lfs (SOME l0) lfs =
   190   | chain_qs_lfs (SOME l0) lfs =
   150     if member (op =) lfs l0 then ([Then], remove (op =) l0 lfs) else ([], lfs)
   191     if member (op =) lfs l0 then ([Then], remove (op =) l0 lfs) else ([], lfs)
   151 
   192 
   152 fun chain_isar_step lbl (Prove (qs, xs, l, t, subs, (lfs, gfs), meths, comment)) =
   193 fun chain_isar_step lbl (Prove {qualifiers, obtains, label, goal, subproofs,
       
   194       facts = (lfs, gfs), proof_methods, comment}) =
   153     let val (qs', lfs) = chain_qs_lfs lbl lfs in
   195     let val (qs', lfs) = chain_qs_lfs lbl lfs in
   154       Prove (qs' @ qs, xs, l, t, map chain_isar_proof subs, (lfs, gfs), meths, comment)
   196       Prove {
       
   197         qualifiers = qs' @ qualifiers,
       
   198         obtains = obtains,
       
   199         label = label,
       
   200         goal = goal,
       
   201         subproofs = map chain_isar_proof subproofs,
       
   202         facts = (lfs, gfs),
       
   203         proof_methods = proof_methods,
       
   204         comment = comment}
   155     end
   205     end
   156   | chain_isar_step _ step = step
   206   | chain_isar_step _ step = step
   157 and chain_isar_steps _ [] = []
   207 and chain_isar_steps _ [] = []
   158   | chain_isar_steps prev (i :: is) =
   208   | chain_isar_steps prev (i :: is) =
   159     chain_isar_step prev i :: chain_isar_steps (label_of_isar_step i) is
   209     chain_isar_step prev i :: chain_isar_steps (label_of_isar_step i) is
   165     val used_ls =
   215     val used_ls =
   166       fold_isar_steps (facts_of_isar_step #> fst #> union (op =)) (steps_of_isar_proof proof) []
   216       fold_isar_steps (facts_of_isar_step #> fst #> union (op =)) (steps_of_isar_proof proof) []
   167 
   217 
   168     fun kill_label l = if member (op =) used_ls l then l else no_label
   218     fun kill_label l = if member (op =) used_ls l then l else no_label
   169 
   219 
   170     fun kill_step (Prove (qs, xs, l, t, subs, facts, meths, comment)) =
   220     fun kill_step (Prove {qualifiers, obtains, label, goal, subproofs, facts, proof_methods,
   171         Prove (qs, xs, kill_label l, t, map kill_proof subs, facts, meths, comment)
   221           comment}) =
       
   222         Prove {
       
   223           qualifiers = qualifiers,
       
   224           obtains = obtains,
       
   225           label = kill_label label,
       
   226           goal = goal,
       
   227           subproofs = map kill_proof subproofs,
       
   228           facts = facts,
       
   229           proof_methods = proof_methods,
       
   230           comment = comment}
   172       | kill_step step = step
   231       | kill_step step = step
   173     and kill_proof (Proof {fixes, assumptions, steps}) =
   232     and kill_proof (Proof {fixes, assumptions, steps}) =
   174       let
   233       let
   175         val assumptions' = map (apfst kill_label) assumptions
   234         val assumptions' = map (apfst kill_label) assumptions
   176         val steps' = map kill_step steps
   235         val steps' = map kill_step steps
   184 fun relabel_isar_proof_canonically proof =
   243 fun relabel_isar_proof_canonically proof =
   185   let
   244   let
   186     fun next_label l (next, subst) =
   245     fun next_label l (next, subst) =
   187       let val l' = ("", next) in (l', (next + 1, (l, l') :: subst)) end
   246       let val l' = ("", next) in (l', (next + 1, (l, l') :: subst)) end
   188 
   247 
   189     fun relabel_step (Prove (qs, fix, l, t, subs, (lfs, gfs), meths, comment))
   248     fun relabel_step (Prove {qualifiers, obtains, label, goal, subproofs, facts = (lfs, gfs),
   190           (accum as (_, subst)) =
   249           proof_methods, comment}) (accum as (_, subst)) =
   191         let
   250         let
   192           val lfs' = maps (the_list o AList.lookup (op =) subst) lfs
   251           val lfs' = maps (the_list o AList.lookup (op =) subst) lfs
   193           val ((subs', l'), accum') = accum
   252           val ((subs', l'), accum') = accum
   194             |> fold_map relabel_proof subs
   253             |> fold_map relabel_proof subproofs
   195             ||>> next_label l
   254             ||>> next_label label
       
   255           val prove = Prove {
       
   256             qualifiers = qualifiers,
       
   257             obtains = obtains,
       
   258             label = l',
       
   259             goal = goal,
       
   260             subproofs = subs',
       
   261             facts = (lfs', gfs),
       
   262             proof_methods = proof_methods,
       
   263             comment = comment}
   196         in
   264         in
   197           (Prove (qs, fix, l', t, subs', (lfs', gfs), meths, comment), accum')
   265           (prove, accum')
   198         end
   266         end
   199       | relabel_step step accum = (step, accum)
   267       | relabel_step step accum = (step, accum)
   200     and relabel_proof (Proof {fixes, assumptions, steps}) =
   268     and relabel_proof (Proof {fixes, assumptions, steps}) =
   201       fold_map (fn (l, t) => next_label l #> apfst (rpair t)) assumptions
   269       fold_map (fn (l, t) => next_label l #> apfst (rpair t)) assumptions
   202       ##>> fold_map relabel_step steps
   270       ##>> fold_map relabel_step steps
   214       else
   282       else
   215         let val l' = (replicate_string (depth + 1) prefix, next) in
   283         let val l' = (replicate_string (depth + 1) prefix, next) in
   216           (l', (next + 1, (l, l') :: subst))
   284           (l', (next + 1, (l, l') :: subst))
   217         end
   285         end
   218 
   286 
   219     fun relabel_step depth (Prove (qs, xs, l, t, subs, (lfs, gfs), meths, comment))
   287     fun relabel_step depth (Prove {qualifiers, obtains, label, goal,
   220           (accum as (_, subst)) =
   288           subproofs, facts = (lfs, gfs), proof_methods, comment}) (accum as (_, subst)) =
   221         let
   289         let
   222           val lfs' = maps (the_list o AList.lookup (op =) subst) lfs
   290           val (l', accum' as (_, subst')) = next_label depth have_prefix label accum
   223           val (l', accum' as (_, subst')) = next_label depth have_prefix l accum
   291           val prove = Prove {
   224           val subs' = map (relabel_proof subst' (depth + 1)) subs
   292             qualifiers = qualifiers,
       
   293             obtains = obtains,
       
   294             label = l',
       
   295             goal = goal,
       
   296             subproofs = map (relabel_proof subst' (depth + 1)) subproofs,
       
   297             facts = (maps (the_list o AList.lookup (op =) subst) lfs, gfs),
       
   298             proof_methods = proof_methods,
       
   299             comment = comment}
   225         in
   300         in
   226           (Prove (qs, xs, l', t, subs', (lfs', gfs), meths, comment), accum')
   301           (prove, accum')
   227         end
   302         end
   228       | relabel_step _ step accum = (step, accum)
   303       | relabel_step _ step accum = (step, accum)
   229     and relabel_proof subst depth (Proof {fixes, assumptions, steps}) =
   304     and relabel_proof subst depth (Proof {fixes, assumptions, steps}) =
   230       (1, subst)
   305       (1, subst)
   231       |> fold_map (fn (l, t) => next_label depth assume_prefix l #> apfst (rpair t)) assumptions
   306       |> fold_map (fn (l, t) => next_label depth assume_prefix l #> apfst (rpair t)) assumptions
   248         val ys = map2 pair new_names Ts
   323         val ys = map2 pair new_names Ts
   249       in
   324       in
   250         (ys, ((map Free xs ~~ map Free ys) @ subst, ctxt'))
   325         (ys, ((map Free xs ~~ map Free ys) @ subst, ctxt'))
   251       end
   326       end
   252 
   327 
   253     fun rationalize_step (Prove (qs, xs, l, t, subs, facts, meths, comment)) subst_ctxt =
   328     fun rationalize_step (Prove {qualifiers, obtains, label, goal, subproofs, facts, proof_methods,
       
   329           comment}) subst_ctxt =
   254         let
   330         let
   255           val (xs', subst_ctxt' as (subst', _)) = rename_obtains xs subst_ctxt
   331           val (obtains', subst_ctxt' as (subst', _)) = rename_obtains obtains subst_ctxt
   256           val t' = subst_atomic subst' t
   332           val prove = Prove {
   257           val subs' = map (rationalize_proof false subst_ctxt') subs
   333             qualifiers = qualifiers,
       
   334             obtains = obtains',
       
   335             label = label,
       
   336             goal = subst_atomic subst' goal,
       
   337             subproofs = map (rationalize_proof false subst_ctxt') subproofs,
       
   338             facts = facts,
       
   339             proof_methods = proof_methods,
       
   340             comment = comment}
   258         in
   341         in
   259           (Prove (qs, xs', l, t', subs', facts, meths, comment), subst_ctxt')
   342           (prove, subst_ctxt')
   260         end
   343         end
   261     and rationalize_proof outer (subst_ctxt as (subst, ctxt)) (Proof {fixes, assumptions, steps}) =
   344     and rationalize_proof outer (subst_ctxt as (subst, ctxt)) (Proof {fixes, assumptions, steps}) =
   262       let
   345       let
   263         val (fixes', subst_ctxt' as (subst', _)) =
   346         val (fixes', subst_ctxt' as (subst', _)) =
   264           if outer then
   347           if outer then
   365       | of_subproofs ind ctxt qs subs =
   448       | of_subproofs ind ctxt qs subs =
   366         (if member (op =) qs Then then of_moreover ind else "") ^
   449         (if member (op =) qs Then then of_moreover ind else "") ^
   367         space_implode (of_moreover ind) (map (of_subproof ind ctxt) subs)
   450         space_implode (of_moreover ind) (map (of_subproof ind ctxt) subs)
   368     and add_step_pre ind qs subs (s, ctxt) =
   451     and add_step_pre ind qs subs (s, ctxt) =
   369       (s ^ of_subproofs ind ctxt qs subs ^ of_indent ind, ctxt)
   452       (s ^ of_subproofs ind ctxt qs subs ^ of_indent ind, ctxt)
   370     and add_step ind (Let (t1, t2)) =
   453     and add_step ind (Let {lhs = t1, rhs = t2}) =
   371         add_str (of_indent ind ^ "let ") #> add_term t1 #> add_str " = " #> add_term t2
   454         add_str (of_indent ind ^ "let ") #> add_term t1 #> add_str " = " #> add_term t2
   372         #> add_str "\n"
   455         #> add_str "\n"
   373       | add_step ind (Prove (qs, xs, l, t, subs, (ls, ss), meth :: _, comment)) =
   456       | add_step ind (Prove {qualifiers, obtains, label, goal, subproofs, facts = (ls, ss),
   374         add_step_pre ind qs subs
   457           proof_methods = meth :: _, comment}) =
   375         #> (case xs of
   458         let val num_subproofs = length subproofs in
   376             [] => add_str (of_have qs (length subs) ^ " ")
   459           add_step_pre ind qualifiers subproofs
   377           | _ =>
   460           #> (case obtains of
   378             add_str (of_obtain qs (length subs) ^ " ")
   461               [] => add_str (of_have qualifiers num_subproofs ^ " ")
   379             #> add_frees xs
   462             | _ =>
   380             #> add_str (" where\n" ^ of_indent (ind + 1)))
   463               add_str (of_obtain qualifiers num_subproofs ^ " ")
   381         #> add_str (of_label l)
   464               #> add_frees obtains
   382         #> add_term (if is_thesis ctxt t then HOLogic.mk_Trueprop (Var thesis_var) else t)
   465               #> add_str (" where\n" ^ of_indent (ind + 1)))
   383         #> add_str ("\n" ^ of_indent (ind + 1) ^ of_method ls ss meth ^
   466           #> add_str (of_label label)
   384           (if comment = "" then "" else " (* " ^ comment ^ " *)") ^ "\n")
   467           #> add_term (if is_thesis ctxt goal then HOLogic.mk_Trueprop (Var thesis_var) else goal)
       
   468           #> add_str ("\n" ^ of_indent (ind + 1) ^ of_method ls ss meth ^
       
   469             (if comment = "" then "" else " (* " ^ comment ^ " *)") ^ "\n")
       
   470         end
   385     and add_steps ind = fold (add_step ind)
   471     and add_steps ind = fold (add_step ind)
   386     and of_proof ind ctxt (Proof {fixes, assumptions, steps}) =
   472     and of_proof ind ctxt (Proof {fixes, assumptions, steps}) =
   387       ("", ctxt)
   473       ("", ctxt)
   388       |> add_fix ind fixes
   474       |> add_fix ind fixes
   389       |> fold (add_assm ind) assumptions
   475       |> fold (add_assm ind) assumptions