src/HOL/Tools/Sledgehammer/sledgehammer_reconstruct.ML
changeset 54755 2eb43ddde491
parent 54754 6b0ca7f79e93
child 54756 dd0f4d265730
equal deleted inserted replaced
54754:6b0ca7f79e93 54755:2eb43ddde491
    60 val z3_skolemize_rule = "sk"
    60 val z3_skolemize_rule = "sk"
    61 val z3_th_lemma_rule = "th-lemma"
    61 val z3_th_lemma_rule = "th-lemma"
    62 
    62 
    63 val is_skolemize_rule =
    63 val is_skolemize_rule =
    64   member (op =) [e_skolemize_rule, vampire_skolemisation_rule, z3_skolemize_rule]
    64   member (op =) [e_skolemize_rule, vampire_skolemisation_rule, z3_skolemize_rule]
       
    65 
       
    66 val is_arith_rule = String.isPrefix z3_th_lemma_rule
    65 
    67 
    66 fun raw_label_of_num num = (num, 0)
    68 fun raw_label_of_num num = (num, 0)
    67 
    69 
    68 fun label_of_clause [(num, _)] = raw_label_of_num num
    70 fun label_of_clause [(num, _)] = raw_label_of_num num
    69   | label_of_clause c = (space_implode "___" (map (fst o raw_label_of_num o fst) c), 0)
    71   | label_of_clause c = (space_implode "___" (map (fst o raw_label_of_num o fst) c), 0)
   120    clsarity). *)
   122    clsarity). *)
   121 fun is_only_type_information t = t aconv @{term True}
   123 fun is_only_type_information t = t aconv @{term True}
   122 
   124 
   123 (* Discard facts; consolidate adjacent lines that prove the same formula, since
   125 (* Discard facts; consolidate adjacent lines that prove the same formula, since
   124    they differ only in type information.*)
   126    they differ only in type information.*)
   125 fun add_line (line as (name as (_, ss), role, t, rule, [])) lines =
   127 fun add_line_pass1 (line as (name as (_, ss), role, t, rule, [])) lines =
   126     (* No dependencies: lemma (for Z3), fact, conjecture, or (for Vampire)
   128     (* No dependencies: lemma (for Z3), fact, conjecture, or (for Vampire)
   127        internal facts or definitions. *)
   129        internal facts or definitions. *)
   128     if role = Lemma orelse role = Conjecture orelse role = Negated_Conjecture orelse
   130     if role = Lemma orelse role = Conjecture orelse role = Negated_Conjecture orelse
   129        role = Hypothesis then
   131        role = Hypothesis orelse is_arith_rule rule then
   130       line :: lines
   132       line :: lines
   131     else if role = Axiom then
   133     else if role = Axiom then
   132       (* Facts are not proof lines. *)
   134       (* Facts are not proof lines. *)
   133       lines |> is_only_type_information t ? map (replace_dependencies_in_line (name, []))
   135       lines |> is_only_type_information t ? map (replace_dependencies_in_line (name, []))
   134     else
   136     else
   135       map (replace_dependencies_in_line (name, [])) lines
   137       map (replace_dependencies_in_line (name, [])) lines
   136   | add_line line lines = line :: lines
   138   | add_line_pass1 line lines = line :: lines
   137 
   139 
   138 (* Recursively delete empty lines (type information) from the proof. *)
   140 (* Recursively delete empty lines (type information) from the proof. *)
   139 fun add_nontrivial_line (line as (name, _, t, _, [])) lines =
   141 fun add_line_pass2 (line as (name, _, t, _, [])) lines =
   140     if is_only_type_information t then delete_dependency name lines else line :: lines
   142     if is_only_type_information t then delete_dependency name lines else line :: lines
   141   | add_nontrivial_line line lines = line :: lines
   143   | add_line_pass2 line lines = line :: lines
   142 and delete_dependency name lines =
   144 and delete_dependency name lines =
   143   fold_rev add_nontrivial_line (map (replace_dependencies_in_line (name, [])) lines) []
   145   fold_rev add_line_pass2 (map (replace_dependencies_in_line (name, [])) lines) []
   144 
   146 
   145 fun add_desired_lines res [] = rev res
   147 fun add_line_pass3 res [] = rev res
   146   | add_desired_lines res ((name as (_, ss), role, t, rule, deps) :: lines) =
   148   | add_line_pass3 res ((line as (name as (_, ss), role, t, rule, deps)) :: lines) =
   147     if role <> Plain orelse is_skolemize_rule rule orelse
   149     if role <> Plain orelse is_skolemize_rule rule orelse is_arith_rule rule orelse
   148        (* the last line must be kept *)
   150        (* the last line must be kept *)
   149        null lines orelse
   151        null lines orelse
   150        (not (is_only_type_information t) andalso null (Term.add_tvars t [])
   152        (not (is_only_type_information t) andalso null (Term.add_tvars t [])
   151         andalso length deps >= 2 andalso
   153         andalso length deps >= 2 andalso
   152         (* don't keep next to last line, which usually results in a trivial step *)
   154         (* don't keep next to last line, which usually results in a trivial step *)
   153         not (can the_single lines)) then
   155         not (can the_single lines)) then
   154       add_desired_lines ((name, role, t, rule, deps) :: res) lines
   156       add_line_pass3 (line :: res) lines
   155     else
   157     else
   156       add_desired_lines res (map (replace_dependencies_in_line (name, deps)) lines)
   158       add_line_pass3 res (map (replace_dependencies_in_line (name, deps)) lines)
   157 
   159 
   158 val add_labels_of_proof =
   160 val add_labels_of_proof =
   159   steps_of_proof
   161   steps_of_proof
   160   #> fold_isar_steps (byline_of_step #> (fn SOME ((ls, _), _) => union (op =) ls | _ => I))
   162   #> fold_isar_steps (byline_of_step #> (fn SOME ((ls, _), _) => union (op =) ls | _ => I))
   161 
   163 
   264       let
   266       let
   265         val atp_proof =
   267         val atp_proof =
   266           atp_proof
   268           atp_proof
   267           |> inline_z3_defs []
   269           |> inline_z3_defs []
   268           |> inline_z3_hypotheses [] []
   270           |> inline_z3_hypotheses [] []
   269           |> rpair [] |-> fold_rev add_line
   271           |> rpair [] |-> fold_rev add_line_pass1
   270           |> rpair [] |-> fold_rev add_nontrivial_line
   272           |> rpair [] |-> fold_rev add_line_pass2
   271           |> add_desired_lines []
   273           |> add_line_pass3 []
   272 
   274 
   273         val conjs =
   275         val conjs =
   274           map_filter (fn (name, role, _, _, _) =>
   276           map_filter (fn (name, role, _, _, _) =>
   275               if member (op =) [Conjecture, Negated_Conjecture] role then SOME name else NONE)
   277               if member (op =) [Conjecture, Negated_Conjecture] role then SOME name else NONE)
   276             atp_proof
   278             atp_proof
   279           map_filter (get_role (curry (op =) Lemma)) atp_proof
   281           map_filter (get_role (curry (op =) Lemma)) atp_proof
   280           |> map (fn ((l, t), rule) =>
   282           |> map (fn ((l, t), rule) =>
   281             let
   283             let
   282               val (skos, meth) =
   284               val (skos, meth) =
   283                 if is_skolemize_rule rule then (skolems_of t, MetisM)
   285                 if is_skolemize_rule rule then (skolems_of t, MetisM)
   284                 else if rule = z3_th_lemma_rule then ([], ArithM)
   286                 else if is_arith_rule rule then ([], ArithM)
   285                 else ([], SimpM)
   287                 else ([], AutoM)
   286             in
   288             in
   287               Prove ([], skos, l, maybe_mk_Trueprop t, [], (([], []), meth))
   289               Prove ([], skos, l, maybe_mk_Trueprop t, [], (([], []), meth))
   288             end)
   290             end)
   289 
   291 
   290         val bot = atp_proof |> List.last |> #1
   292         val bot = atp_proof |> List.last |> #1
   308                                 #> fold exists_of (map Var (Term.add_vars t []))
   310                                 #> fold exists_of (map Var (Term.add_vars t []))
   309                               else
   311                               else
   310                                 I))))
   312                                 I))))
   311                   atp_proof
   313                   atp_proof
   312 
   314 
   313         fun is_clause_skolemize_rule [(s, _)] =
   315         val rule_of_clause_id = fst o the o Symtab.lookup steps o fst
   314             Option.map (is_skolemize_rule o fst) (Symtab.lookup steps s) = SOME true
       
   315           | is_clause_skolemize_rule _ = false
       
   316 
   316 
   317         (* The assumptions and conjecture are "prop"s; the other formulas are "bool"s (for ATPs) or
   317         (* The assumptions and conjecture are "prop"s; the other formulas are "bool"s (for ATPs) or
   318            "prop"s (for Z3). TODO: Always use "prop". *)
   318            "prop"s (for Z3). TODO: Always use "prop". *)
   319         fun prop_of_clause [(num, _)] =
   319         fun prop_of_clause [(num, _)] =
   320             Symtab.lookup steps num |> the |> snd |> maybe_mk_Trueprop |> close_form
   320             Symtab.lookup steps num |> the |> snd |> maybe_mk_Trueprop |> close_form
   335 
   335 
   336         fun isar_steps outer predecessor accum [] =
   336         fun isar_steps outer predecessor accum [] =
   337             accum
   337             accum
   338             |> (if tainted = [] then
   338             |> (if tainted = [] then
   339                   cons (Prove (if outer then [Show] else [], [], no_label, concl_t, [],
   339                   cons (Prove (if outer then [Show] else [], [], no_label, concl_t, [],
   340                                (([the predecessor], []), MetisM)))
   340                                ((the_list predecessor, []), MetisM)))
   341                 else
   341                 else
   342                   I)
   342                   I)
   343             |> rev
   343             |> rev
   344           | isar_steps outer _ accum (Have (gamma, c) :: infs) =
   344           | isar_steps outer _ accum (Have (id, (gamma, c)) :: infs) =
   345             let
   345             let
   346               val l = label_of_clause c
   346               val l = label_of_clause c
   347               val t = prop_of_clause c
   347               val t = prop_of_clause c
   348               val by = (fold add_fact_of_dependencies gamma no_facts, MetisM)
   348               val rule = rule_of_clause_id id
       
   349               val skolem = is_skolemize_rule rule
       
   350 
   349               fun prove sub by = Prove (maybe_show outer c [], [], l, t, sub, by)
   351               fun prove sub by = Prove (maybe_show outer c [], [], l, t, sub, by)
   350               fun do_rest l step = isar_steps outer (SOME l) (step :: accum) infs
   352               fun do_rest l step = isar_steps outer (SOME l) (step :: accum) infs
       
   353 
       
   354               val deps = fold add_fact_of_dependencies gamma no_facts
       
   355               val meth = if is_arith_rule rule then ArithM else MetisM
       
   356               val by = (deps, meth)
   351             in
   357             in
   352               if is_clause_tainted c then
   358               if is_clause_tainted c then
   353                 (case gamma of
   359                 (case gamma of
   354                   [g] =>
   360                   [g] =>
   355                   if is_clause_skolemize_rule g andalso is_clause_tainted g then
   361                   if skolem andalso is_clause_tainted g then
   356                     let val subproof = Proof (skolems_of (prop_of_clause g), [], rev accum) in
   362                     let val subproof = Proof (skolems_of (prop_of_clause g), [], rev accum) in
   357                       isar_steps outer (SOME l) [prove [subproof] (no_facts, MetisM)] []
   363                       isar_steps outer (SOME l) [prove [subproof] (no_facts, MetisM)] []
   358                     end
   364                     end
   359                   else
   365                   else
   360                     do_rest l (prove [] by)
   366                     do_rest l (prove [] by)
   361                 | _ => do_rest l (prove [] by))
   367                 | _ => do_rest l (prove [] by))
   362               else
   368               else
   363                 (if is_clause_skolemize_rule c then Prove ([], skolems_of t, l, t, [], by)
   369                 (if skolem then Prove ([], skolems_of t, l, t, [], by)
   364                  else prove [] by)
   370                  else prove [] by)
   365                 |> do_rest l
   371                 |> do_rest l
   366             end
   372             end
   367           | isar_steps outer predecessor accum (Cases cases :: infs) =
   373           | isar_steps outer predecessor accum (Cases cases :: infs) =
   368             let
   374             let