src/HOL/Tools/Sledgehammer/sledgehammer_reconstruct.ML
changeset 52454 b528a975b256
parent 52453 2cba5906d836
child 52555 6811291d1869
equal deleted inserted replaced
52453:2cba5906d836 52454:b528a975b256
   517         add_suffix (of_indent ind ^ "let ")
   517         add_suffix (of_indent ind ^ "let ")
   518         #> add_term t1
   518         #> add_term t1
   519         #> add_suffix " = "
   519         #> add_suffix " = "
   520         #> add_term t2
   520         #> add_term t2
   521         #> add_suffix "\n"
   521         #> add_suffix "\n"
   522       | add_step ind (Prove (qs, Fix xs, l, t, By_Metis (subproofs, facts))) =
   522       | add_step ind (Prove (qs, Fix xs, l, t, subproofs, By_Metis facts)) =
   523         (case xs of
   523         (case xs of
   524           [] => (* have *)
   524           [] => (* have *)
   525             add_step_pre ind qs subproofs
   525             add_step_pre ind qs subproofs
   526             #> add_suffix (of_prove qs (length subproofs) ^ " ")
   526             #> add_suffix (of_prove qs (length subproofs) ^ " ")
   527             #> add_step_post ind l t facts ""
   527             #> add_step_post ind l t facts ""
   547       |> fst
   547       |> fst
   548   in
   548   in
   549     (* One-step proofs are pointless; better use the Metis one-liner
   549     (* One-step proofs are pointless; better use the Metis one-liner
   550        directly. *)
   550        directly. *)
   551     case proof of
   551     case proof of
   552       Proof (Fix [], Assume [], [Prove (_, Fix [], _, _, By_Metis ([], _))]) => ""
   552       Proof (Fix [], Assume [], [Prove (_, Fix [], _, _, [], _)]) => ""
   553     | _ => (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^
   553     | _ => (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^
   554             of_indent 0 ^ "proof -\n" ^ of_proof 1 ctxt proof ^
   554             of_indent 0 ^ "proof -\n" ^ of_proof 1 ctxt proof ^
   555             of_indent 0 ^ (if n <> 1 then "next" else "qed")
   555             of_indent 0 ^ (if n <> 1 then "next" else "qed")
   556   end
   556   end
   557 
   557 
   558 fun add_labels_of_step step =
   558 val add_labels_of_proof =
   559   case byline_of_step step of
   559   steps_of_proof #> fold_isar_steps
   560     NONE => I
   560     (byline_of_step #> (fn SOME (By_Metis (ls, _)) => union (op =) ls
   561   | SOME (By_Metis (subproofs, (ls, _))) =>
   561                          | _ => I))
   562     union (op =) ls #> fold add_labels_of_proof subproofs
       
   563 and add_labels_of_proof proof = fold add_labels_of_step (steps_of_proof proof)
       
   564 
   562 
   565 fun kill_useless_labels_in_proof proof =
   563 fun kill_useless_labels_in_proof proof =
   566   let
   564   let
   567     val used_ls = add_labels_of_proof proof []
   565     val used_ls = add_labels_of_proof proof []
   568     fun do_label l = if member (op =) used_ls l then l else no_label
   566     fun do_label l = if member (op =) used_ls l then l else no_label
   569     fun do_assms (Assume assms) = Assume (map (apfst do_label) assms)
   567     fun do_assms (Assume assms) = Assume (map (apfst do_label) assms)
   570     fun do_step (Prove (qs, xs, l, t, By_Metis (subproofs, facts))) =
   568     fun do_step (Prove (qs, xs, l, t, subproofs, by)) =
   571           Prove (qs, xs, do_label l, t, By_Metis (map do_proof subproofs, facts))
   569           Prove (qs, xs, do_label l, t, map do_proof subproofs, by)
   572       | do_step step = step
   570       | do_step step = step
   573     and do_proof (Proof (fix, assms, steps)) =
   571     and do_proof (Proof (fix, assms, steps)) =
   574           Proof (fix, do_assms assms, map do_step steps)
   572           Proof (fix, do_assms assms, map do_step steps)
   575   in do_proof proof end
   573   in do_proof proof end
   576 
   574 
   597     fun do_assms subst depth (Assume assms) =
   595     fun do_assms subst depth (Assume assms) =
   598       fold_map (do_assm depth) assms (subst, 1)
   596       fold_map (do_assm depth) assms (subst, 1)
   599       |> apfst Assume
   597       |> apfst Assume
   600       |> apsnd fst
   598       |> apsnd fst
   601     fun do_steps _ _ _ [] = []
   599     fun do_steps _ _ _ [] = []
   602       | do_steps subst depth next (Prove (qs, xs, l, t, by) :: steps) =
   600       | do_steps subst depth next (Prove (qs, xs, l, t, sub, by) :: steps) =
   603         let
   601         let
   604           val (l, subst, next) =
   602           val (l, subst, next) =
   605             (l, subst, next) |> fresh_label depth have_prefix
   603             (l, subst, next) |> fresh_label depth have_prefix
       
   604           val sub = do_proofs subst depth sub
   606           val by = by |> do_byline subst depth
   605           val by = by |> do_byline subst depth
   607         in Prove (qs, xs, l, t, by) :: do_steps subst depth next steps end
   606         in Prove (qs, xs, l, t, sub, by) :: do_steps subst depth next steps end
   608       | do_steps subst depth next (step :: steps) =
   607       | do_steps subst depth next (step :: steps) =
   609         step :: do_steps subst depth next steps
   608         step :: do_steps subst depth next steps
   610     and do_proof subst depth (Proof (fix, assms, steps)) =
   609     and do_proof subst depth (Proof (fix, assms, steps)) =
   611       let val (assms, subst) = do_assms subst depth assms in
   610       let val (assms, subst) = do_assms subst depth assms in
   612         Proof (fix, assms, do_steps subst depth 1 steps)
   611         Proof (fix, assms, do_steps subst depth 1 steps)
   613       end
   612       end
   614     and do_byline subst depth (By_Metis (subproofs, facts)) =
   613     and do_byline subst depth (By_Metis facts) =
   615       By_Metis (do_proofs subst depth subproofs, do_facts subst facts)
   614       By_Metis (do_facts subst facts)
   616     and do_proofs subst depth = map (do_proof subst (depth + 1))
   615     and do_proofs subst depth = map (do_proof subst (depth + 1))
   617   in do_proof [] 0 end
   616   in do_proof [] 0 end
   618 
   617 
   619 val chain_direct_proof =
   618 val chain_direct_proof =
   620   let
   619   let
   621     fun do_qs_lfs NONE lfs = ([], lfs)
   620     fun do_qs_lfs NONE lfs = ([], lfs)
   622       | do_qs_lfs (SOME l0) lfs =
   621       | do_qs_lfs (SOME l0) lfs =
   623         if member (op =) lfs l0 then ([Then], lfs |> remove (op =) l0)
   622         if member (op =) lfs l0 then ([Then], lfs |> remove (op =) l0)
   624         else ([], lfs)
   623         else ([], lfs)
   625     fun chain_step lbl (Prove (qs, xs, l, t,
   624     fun chain_step lbl (Prove (qs, xs, l, t, subproofs, By_Metis (lfs, gfs))) =
   626                                 By_Metis (subproofs, (lfs, gfs)))) =
       
   627           let val (qs', lfs) = do_qs_lfs lbl lfs in
   625           let val (qs', lfs) = do_qs_lfs lbl lfs in
   628             Prove (qs' @ qs, xs, l, t,
   626             Prove (qs' @ qs, xs, l, t, chain_proofs subproofs,
   629               By_Metis (chain_proofs subproofs, (lfs, gfs)))
   627                    By_Metis (lfs, gfs))
   630           end
   628           end
   631       | chain_step _ step = step
   629       | chain_step _ step = step
   632     and chain_steps _ [] = []
   630     and chain_steps _ [] = []
   633       | chain_steps (prev as SOME _) (i :: is) =
   631       | chain_steps (prev as SOME _) (i :: is) =
   634         chain_step prev i :: chain_steps (label_of_step i) is
   632         chain_step prev i :: chain_steps (label_of_step i) is
   743               Term.add_frees t [] |> filter_out (is_fixed o fst) |> rev
   741               Term.add_frees t [] |> filter_out (is_fixed o fst) |> rev
   744             fun do_steps outer predecessor accum [] =
   742             fun do_steps outer predecessor accum [] =
   745                 accum
   743                 accum
   746                 |> (if tainted = [] then
   744                 |> (if tainted = [] then
   747                       cons (Prove (if outer then [Show] else [],
   745                       cons (Prove (if outer then [Show] else [],
   748                                    Fix [], no_label, concl_t,
   746                                    Fix [], no_label, concl_t, [],
   749                                    By_Metis ([], ([the predecessor], []))))
   747                                    By_Metis ([the predecessor], [])))
   750                     else
   748                     else
   751                       I)
   749                       I)
   752                 |> rev
   750                 |> rev
   753               | do_steps outer _ accum (Have (gamma, c) :: infs) =
   751               | do_steps outer _ accum (Have (gamma, c) :: infs) =
   754                 let
   752                 let
   755                   val l = label_of_clause c
   753                   val l = label_of_clause c
   756                   val t = prop_of_clause c
   754                   val t = prop_of_clause c
   757                   val by =
   755                   val by =
   758                     By_Metis ([],
   756                     By_Metis
   759                       (fold (add_fact_of_dependencies fact_names)
   757                       (fold (add_fact_of_dependencies fact_names) gamma no_facts)
   760                             gamma no_facts))
   758                   fun prove sub by =
   761                   fun prove by = Prove (maybe_show outer c [], Fix [], l, t, by)
   759                     Prove (maybe_show outer c [], Fix [], l, t, sub, by)
   762                   fun do_rest l step =
   760                   fun do_rest l step =
   763                     do_steps outer (SOME l) (step :: accum) infs
   761                     do_steps outer (SOME l) (step :: accum) infs
   764                 in
   762                 in
   765                   if is_clause_tainted c then
   763                   if is_clause_tainted c then
   766                     case gamma of
   764                     case gamma of
   771                           val subproof =
   769                           val subproof =
   772                             Proof (Fix (skolems_of (prop_of_clause g)),
   770                             Proof (Fix (skolems_of (prop_of_clause g)),
   773                                    Assume [], rev accum)
   771                                    Assume [], rev accum)
   774                         in
   772                         in
   775                           do_steps outer (SOME l)
   773                           do_steps outer (SOME l)
   776                               [prove (By_Metis ([subproof], no_facts))] []
   774                               [prove [subproof] (By_Metis no_facts)] []
   777                         end
   775                         end
   778                       else
   776                       else
   779                         do_rest l (prove by)
   777                         do_rest l (prove [] by)
   780                     | _ => do_rest l (prove by)
   778                     | _ => do_rest l (prove [] by)
   781                   else
   779                   else
   782                     if is_clause_skolemize_rule c then
   780                     if is_clause_skolemize_rule c then
   783                       do_rest l (Prove ([], Fix (skolems_of t), l, t, by))
   781                       do_rest l (Prove ([], Fix (skolems_of t), l, t, [], by))
   784                     else
   782                     else
   785                       do_rest l (prove by)
   783                       do_rest l (prove [] by)
   786                 end
   784                 end
   787               | do_steps outer predecessor accum (Cases cases :: infs) =
   785               | do_steps outer predecessor accum (Cases cases :: infs) =
   788                 let
   786                 let
   789                   fun do_case (c, infs) =
   787                   fun do_case (c, infs) =
   790                     do_proof false [] [(label_of_clause c, prop_of_clause c)]
   788                     do_proof false [] [(label_of_clause c, prop_of_clause c)]
   792                   val c = succedent_of_cases cases
   790                   val c = succedent_of_cases cases
   793                   val l = label_of_clause c
   791                   val l = label_of_clause c
   794                   val t = prop_of_clause c
   792                   val t = prop_of_clause c
   795                   val step =
   793                   val step =
   796                     Prove (maybe_show outer c [], Fix [], l, t,
   794                     Prove (maybe_show outer c [], Fix [], l, t,
   797                       By_Metis (map do_case cases, (the_list predecessor, [])))
   795                       map do_case cases, By_Metis (the_list predecessor, []))
   798                 in
   796                 in
   799                   do_steps outer (SOME l) (step :: accum) infs
   797                   do_steps outer (SOME l) (step :: accum) infs
   800                 end
   798                 end
   801             and do_proof outer fix assms infs =
   799             and do_proof outer fix assms infs =
   802               Proof (Fix fix, Assume assms, do_steps outer NONE [] infs)
   800               Proof (Fix fix, Assume assms, do_steps outer NONE [] infs)