25#include "StackProver.hpp"
47, action(InferenceItemType::Start)
49, current_depth_limit(0)
51, depth_limit_reached(false)
53, tptp_conversion_string()
57, proof_printer(&stack)
59, output_interval(
params::output_frequency)
65, conjecture_true(false)
66, conjecture_false(false)
67, conjecture_missing(false)
68, negated_conjecture_removed(false)
69, fof_has_axioms(false)
70, simplified_fof_has_axioms(false)
76 path.set_num_preds(n);
80 bool& found_conjecture,
104 if (params::show_clauses) {
105 std::exit(EXIT_SUCCESS);
108 if (
status !=
string(
"") && params::first_parse) {
109 show(1,
string(
"Problem status found: "));
112 if (equality && params::add_equality_axioms) {
113 if (params::first_parse) {
114 show(1,
string(
"Problem involves equality: adding axioms for =."),
true);
115 params::first_parse =
false;
118 if (params::equality_axioms_at_start) {
140 uint32_t max_arity = max_fun_arity;
141 if (max_pred_arity > max_arity)
142 max_arity = max_pred_arity;
147 string xvar(
"__eqx_");
148 string yvar(
"__eqy_");
149 for (
size_t i = 0; i < max_arity; i++) {
161 bool pol = !params::positive_representation;
162 uint32_t n_added = 0;
167 ref.push_back(xs[0]);
168 ref.push_back(xs[0]);
169 Literal reflexive(equals_predicate, ref, 2, pol);
183 Literal sym1(equals_predicate, xy, 2, !pol);
184 Literal sym2(equals_predicate, yx, 2, pol);
199 Literal tr1(equals_predicate, xy, 2, !pol);
200 Literal tr2(equals_predicate, yz, 2, !pol);
201 Literal tr3(equals_predicate, xz, 2, pol);
218 for (
size_t i = 0; i < ar; i++) {
219 x1xn.push_back(xs[i]);
220 y1yn.push_back(ys[i]);
222 xiyi.push_back(xs[i]);
223 xiyi.push_back(ys[i]);
224 Literal eq_lit(equals_predicate, xiyi, 2, !pol);
230 Literal f_lit(equals_predicate, t, 2, pol);
242 if (ar > 0 && p != equals_predicate) {
246 for (
size_t i = 0; i < ar; i++) {
247 x1xn.push_back(xs[i]);
248 y1yn.push_back(ys[i]);
250 xiyi.push_back(xs[i]);
251 xiyi.push_back(ys[i]);
252 Literal eq_lit(equals_predicate, xiyi, 2, !pol);
255 Literal p_lit1(p, x1xn, ar, !pol);
256 Literal p_lit2(p, y1yn, ar, pol);
267 if (!params::no_distinct_objects && min_arity == 0) {
268 vector<Term*> all_distinct_constants;
269 vector<Term*> empty_args;
275 string prefix = name.string::substr(0,params::unique_skolem_prefix.length());
276 bool is_skolem = (params::unique_skolem_prefix.string::compare(0, string::npos, prefix) == 0) &&
277 (params::unique_skolem_prefix.length() < name.length());
278 bool is_quoted = (name[0] ==
'\"' && name[name.size() - 1] ==
'\"');
281 (params::all_distinct_objects || is_quoted)) {
283 all_distinct_constants.push_back(t);
286 size_t s = all_distinct_constants.size();
288 for (
size_t i = s - 1; i > 0; i--) {
289 for (
size_t j = 0; j < i; j++) {
292 args.push_back(all_distinct_constants[i]);
293 args.push_back(all_distinct_constants[j]);
294 Literal eq_lit(equals_predicate, args, 2, !pol);
309 if (params::use_regularity_test && !path.test_for_regularity(
new_C))
341 UnificationOutcome outcome;
352 case InferenceItemType::Lemma:
358 if (params::limit_bt_lemmas)
359 stack[
si].restrict_backtrack();
381 case InferenceItemType::Reduction:
387 if (params::limit_bt_reductions)
388 stack[
si].restrict_backtrack();
417 case InferenceItemType::Extension:
460 outcome =
u(neg_lit, ext_L);
478 cerr <<
"PANIC!!! You should only have a lemmata, reduction or an extension here!"
528 if (params::limit_bt_extensions) {
529 stack[
stack[
si].bt_restriction_index].restrict_backtrack();
585 if (!params::limit_bt_extensions ||
586 ((params::limit_bt_extensions || params::limit_bt_all) &&
587 !params::limit_bt_extensions_left_tree)) {
613 if (params::limit_bt_extensions_left_tree) {
614 size_t target_index =
stack[
si].bt_restriction_index;
616 while (current_index > target_index) {
618 case StackItemType::Lemmata:
620 case StackItemType::Reduction:
623 case StackItemType::LeftBranch:
628 case StackItemType::RightBranch:
631 cerr <<
"Something is VERY WRONG!" << endl;
658 return ProverResult::TimeOut;
663 cout << cursor_symbols::Cursor::to_column(1);
685 case StackItemType::Start:
688 if (
action.
T == InferenceItemType::None)
689 return ProverResult::OptionsExhausted;
700 case StackItemType::Lemmata:
712 return ProverResult::Valid;
721 if (
action.
T == InferenceItemType::None)
756 case StackItemType::Reduction:
766 return ProverResult::Valid;
775 if (
action.
T == InferenceItemType::None)
811 case StackItemType::LeftBranch:
830 if (
action.
T == InferenceItemType::None)
855 case StackItemType::RightBranch:
862 return ProverResult::Valid;
868 if (
action.
T == InferenceItemType::None)
886 cerr <<
"Something is VERY WRONG!" << endl;
890 return ProverResult::Error;
913 if (params::all_start) {
914 for (
size_t i = 0; i < m_size; i++) {
915 results.push_back(StartClauseStatus::Start);
919 bool first_clause_included =
false;
926 if (params::all_pos_neg_start && !params::conjecture_start) {
927 for (
size_t i = 0; i < m_size; i++) {
935 (!(params::restrict_start && first_clause_included))
937 results.push_back(StartClauseStatus::Start);
938 first_clause_included =
true;
941 results.push_back(StartClauseStatus::NoStart);
948 else if (!params::all_pos_neg_start && params::conjecture_start) {
949 for (
size_t i = 0; i < m_size; i++) {
952 (!(params::restrict_start && first_clause_included))) {
953 results.push_back(StartClauseStatus::Start);
954 first_clause_included =
true;
957 results.push_back(StartClauseStatus::NoStart);
968 for (
size_t i = 0; i < m_size; i++) {
977 !(params::restrict_start && first_clause_included)) {
978 results.push_back(StartClauseStatus::Start);
979 first_clause_included =
true;
982 results.push_back(StartClauseStatus::NoStart);
996 if (!first_clause_included) {
997 if (params::verbosity > 2) {
998 cout <<
"Note: you're asking for a conjecture to start, but there are none!" << endl;
999 cout <<
" depending on the other parameter settings, we will use one or " << endl;
1000 cout <<
" all of the negative clauses." << endl;
1005 for (
size_t i = 0; i < m_size; i++) {
1011 !(params::restrict_start && first_clause_included)) {
1012 results.push_back(StartClauseStatus::Start);
1013 first_clause_included =
true;
1016 results.push_back(StartClauseStatus::NoStart);
1032 if (params::deterministic_reorder) {
1035 if (params::random_reorder) {
1038 if (params::random_reorder_literals) {
1046 if (!start_clause.first) {
1047 return ProverOutcome::False;
1065 bool switched_to_complete =
false;
1074 && !switched_to_complete) {
1082 switched_to_complete =
true;
1085 show(1, cs(
"Switching to complete search.").orange(),
true);
1088 show(1,
string(
"SEARCH TO DEPTH: "));
1094 size_t start_clause_index = 0;
1099 if (
results[start_clause_index] == StartClauseStatus::NoStart
1100 ||
results[start_clause_index] == StartClauseStatus::False) {
1101 start_clause_index++;
1124 show(1,
string(
"START from clause "));
1125 show(1, std::to_string(start_clause_index + 1));
1126 show(1,
string(
" of "));
1128 show(2,
string(
": "));
1148 ProverResult result =
go();
1154 case ProverResult::Valid:
1156 if (params::build_proof) {
1157 if (params::generate_LaTeX_proof) {
1162 if (params::generate_LaTeX_tableau_proof) {
1167 if (params::generate_Prolog_proof) {
1168 fs::path prolog_path = params::Prolog_proof_path;
1173 show(1,
string(
": Found proof number "));
1175 return ProverOutcome::Valid;
1177 case ProverResult::Error:
1178 return ProverOutcome::Error;
1180 case ProverResult::TimeOut:
1181 return ProverOutcome::TimeOut;
1183 case ProverResult::OptionsExhausted:
1189 show(1,
string(
": Depth limited"),
true);
1197 results[start_clause_index] = StartClauseStatus::False;
1198 show(1,
string(
": False"),
true);
1201 start_clause_index++;
1204 return ProverOutcome::Error;
1221 bool all_false =
true;
1222 for (StartClauseStatus& outcome :
results) {
1223 if (outcome == StartClauseStatus::Start) {
1229 return ProverOutcome::False;
1234 return ProverOutcome::PathLenLimit;
1241void StackProver::show_stack() {
1242 cout <<
"--------------------------------------------------------" << endl;
1243 cout <<
"Stack:" << endl;
1244 cout <<
"--------------------------------------------------------" << endl;
1245 cout <<
stack << endl;
1246 cout <<
"--------------------------------------------------------" << endl;
1249void StackProver::show_right_stack() {
1250 cout <<
"--------------------------------------------------------" << endl;
1251 cout <<
"Right Stack:" << endl;
1252 cout <<
"--------------------------------------------------------" << endl;
1254 cout <<
"--------------------------------------------------------" << endl;
1259 show(1,
string(
"Reductions: "));
1261 show(1,
string(
" Extensions: "));
1263 show(1,
string(
" Lemmata: "));
1265 show(1,
string(
" Right branches: "));
1271 double s =
static_cast<double>(ms) / 1000.0;
1276 double total_rate = (
static_cast<double>(total) / s);
1277 cout <<
"Reductions: " << setw(15) <<
reductions_tried <<
" (" <<
static_cast<size_t>(red_rate) <<
"/s)" << endl;
1278 cout <<
"Extensions: " << setw(15) <<
extensions_tried <<
" (" <<
static_cast<size_t>(ext_rate) <<
"/s)" << endl;
1279 cout <<
"Lemmas: " << setw(15) <<
lemmata_tried <<
" (" <<
static_cast<size_t>(lem_rate) <<
"/s)" << endl;
1280 cout <<
"Right branches: " << setw(15) <<
right_branches_started <<
" (" <<
static_cast<size_t>(right_rate) <<
"/s)" << endl;
1281 cout <<
"Total: " << setw(15) << total <<
" (" <<
static_cast<size_t>(total_rate) <<
"/s)" << endl;
1284ostream& operator<<(ostream& out,
const StackProver& p) {
1285 out <<
"Current state of the RecursiveProver object" << endl;
1286 out <<
"-------------------------------------------" << endl << endl;
1290 out << p.
path << endl;
void make_copy_with_new_variables(size_t, Clause &, const Matrix &, VariableIndex &, TermIndex &)
If there is a copy cached, replace the parameter with it. Otherwise, use the parameter to actually ma...
void set_size(size_t _s)
Set the number of clauses we need cached copies for.
void backtrack()
Backtracking is just looking at the last copy supplied and undoing that action.
void reset(const Matrix &, VariableIndex &, TermIndex &)
This is for any actual initialisation, when you either (1) intially know what you're dealing with,...
Representation of clauses.
void add_lit(const Literal &)
Add a literal, making sure you don't duplicate.
size_t size() const
Straightforward get method.
string to_string(bool=false) const
Convert to a string.
void drop_literal(LitNum)
Get rid of the specified Literal.
Basic representation of functions.
Arity get_arity() const
Most basic access function.
string get_name() const
Most basic access function.
Arity find_minimum_arity() const
Find the smallest arity appearing for any Function in the index.
size_t get_size() const
Self-explanatory.
Arity find_maximum_arity() const
Find the largest arity appearing for any Function in the index.
Representation of the lemma list.
void push_back(const Literal &)
Self-explanatory.
Basic representation of literals, bundling together (pointers to) a Predicate, a collection of argume...
void move_equals_to_start()
Self-explanatory.
ClauseNum get_num_clauses() const
Straightforward get method.
string make_LaTeX(bool=false) const
Make a usable LaTeX representation.
void add_clause(Clause &, string="")
Add a Clause to the Matrix and update the index accordingly.
bool is_negative(size_t i) const
Is a particular Clause negative?
bool is_conjecture(size_t i) const
Is a particular Clause a conjecture?
void write_to_prolog_file(const path &) const
Write to a file that can be read by Prolog.
void set_num_equals(uint32_t n)
Straightforward set method.
bool is_positive(size_t i) const
Is a particular Clause positive?
void set_num_preds(size_t)
Make an empty index.
pair< bool, size_t > find_start() const
Use a simple heuristic to find a good start clause.
bool is_ground(size_t i) const
Is a particular Clause ground?
Basic representation of predicates: here just names, ids and arities.
Arity get_arity() const
Basic get method.
size_t get_num_preds() const
Basic get method.
Arity find_maximum_arity() const
Find the largest arity appearing in the index.
void make_LaTeX_connection_tableau(const path &, const path &, const string &)
Convert to LaTeX in the connection tableau calculus and store in the specified file.
void make_Prolog(const path &)
Convert to a form suitable for use by the Prolog proof checker and write to a file.
void make_LaTeX(const path &, const path &, const string &)
Convert to LaTeX and store in the specified file.
vector< pair< string, vector< size_t > > > make_internal() const
Make a simple data structure representing the proof stack.
void emplace_back(StackItemType sit, const Clause &_c, const SimplePath &_p, const Lemmata &_l, uint32_t _d)
(Almost!) exact analogue of the same function for vector<>.
size_t size() const
Exact analogue of the same function for vector<>.
bool empty() const
Exact analogue of the same function for vector<>.
void push_back(const StackItem &_item)
Exact analogue of the same function for vector<>.
void pop_back()
Exact analogue of the same function for vector<>. BUT - importantly - avoid calling the StackItem des...
StackItem & back()
Exact analogue of the same function for vector<>.
Prover using a pair of stacks to conduct the proof search.
void set_num_preds(size_t)
Set the number of predicates.
bool depth_limit_reached
Self-explanatary.
void process_axiom_forward()
Start a right branch to continue from an axiom.
string status
Problem status, if found in input file.
void read_from_tptp_file(const string &, bool &, size_t &)
Obviously, reads a problem from a TPTP file.
vector< StartClauseStatus > results
This is populated by the StackProver::set_up_start_clauses method.
bool negated_conjecture_removed
Keep track of whether the parser simplified the conjecture away.
static uint32_t lemmata_tried
We'll be keeping some simple statistics about the search process.
void show_full_statistics(size_t) const
Display counts of number of extensions tried and so on, as well as numbers per second.
void lemmata_backtrack()
One of several different kinds of backtracking.
Stack stack
Main stack: this is constructed by the search process and, if completed, represents a proof.
ClauseCopyCache clause_cache
Manages caching of copies of clauses from the matrix.
void reset_for_start()
Reset everything so that you can start from a specified start clause.
void random_reorder()
Randomly reorder the matrix.
uint32_t current_depth_limit
Self-explanatary.
InferenceItem action
Stores the next action from the current StackItem.
void set_up_start_clauses()
The start clauses to use depend on the settings, and the settings can change.
size_t num_preds
How many prdicates does the problem of interest have?
bool fof_has_axioms
Keep track of whether the parser found that it's an FOF problem with axioms before simplification.
ProverResult go()
This runs the proof search from a given Start Move.
Matrix matrix
A copy of the matrix you're working with.
void deterministic_reorder(uint32_t n)
Deterministically reorder the matrix n times.
bool axiom()
Test to see if you're at an axiom.
PredicateIndex pred_index
This class needs one of each kind of index to keep track of Variables, Terms etc.
ProofPrinter proof_printer
You need one of these to print LaTeX output or any kind of proof certificate.
void extend_with_action()
Take a single inference (action) and update the stacks accordingly.
bool cnf_only
Keep track of whether there were any FOF formulas in the problem file.
SimplePath path
At any point in the search process this is a copy of the path for the current node in the proof being...
FunctionIndex fun_index
This class needs one of each kind of index to keep track of Variables, Terms etc.
void populate_stack_item()
Fill the vector of possible actions with everything available.
Lemmata lemmata
At any point in the search process this is a copy of the list of lemmas for the current node in the p...
void show_statistics() const
Display counts of number of extensions tried and so on.
static uint32_t extensions_tried
We'll be keeping some simple statistics about the search process.
uint32_t current_depth
Self-explanatary.
string tptp_conversion_string
TPTP-friendly description of the clause conversion.
void add_equality_axioms(Predicate *)
After reading a problem in which = and/or != appears, add the axioms for equality.
bool simplified_fof_has_axioms
Keep track of whether the parser found that it's an FOF problem with axioms after simplification.
bool conjecture_missing
Keep track of whether the parser found a conjecture in the problem file.
TermIndex term_index
This class needs one of each kind of index to keep track of Variables, Terms etc.
uint32_t proof_count
If we're searching for multiple proofs, keep count of which one this is.
bool conjecture_false
Keep track of whether the parser found the conjecture to be false.
VariableIndex var_index
This class needs one of each kind of index to keep track of Variables, Terms etc.
void random_reorder_literals()
Randomly reorder the literals in each clause in the matrix.
size_t si
Index of the current StackItem.
void backtrack_once()
Basic, single step backtrack on the stack.
bool conjecture_true
Keep track of whether the parser found the conjecture to be true.
void left_extension_backtrack()
One of several different kinds of backtracking.
static uint32_t right_branches_started
We'll be keeping some simple statistics about the search process.
bool backtrack
Are we moving up or down the stack?
chrono::steady_clock::time_point end_time
When do we stop because of a timeout?
vector< pair< string, vector< size_t > > > get_internal_proof() const
Get an internal representation of the proof stack.
Clause new_C
At any point in the search process this is a copy of the clause for the current node in the proof bei...
void right_extension_backtrack()
One of several different kinds of backtracking.
fs::path problem_path
Path for the problem of interest.
StackProver()
You only need a basic constructor.
bool use_timeout
Are we using a timeout?
Stack right_branch_stack
We build the proof by trying the left branches of extensions first: this stack keeps track of the rig...
void reduction_backtrack()
One of several different kinds of backtracking.
static uint32_t reductions_tried
We'll be keeping some simple statistics about the search process.
SubstitutionStack sub_stack
There is a separate stack to make application and removal of substitutions straightforward.
verbose_print::VPrint show
Set up printing according to verbosity.
Unifier u
We need a single Unifier to use throughout the process.
ProverOutcome prove()
Here is where the magic happens.
Interval output_interval
How often do you output updates about progress?
General representation of a substitution.
void apply() const
Apply a substitution everywhere.
void backtrack()
Remove variables from the stack, and remove substitutions as you go, as far back as the most recent b...
void push_all(Substitution &)
Take all the substitutions provided and add the corresponding variables to the stack.
Wrap up everything the TPTP parser needs to do inside a single class.
bool simplified_fof_has_axioms() const
Where there any axioms for an FOF problem after simplification?
string get_problem_status()
The parse tries to identify the problem status.
void clear()
Clear everything associated with the TPTP parser.
bool parse_tptp_from_file(const string &)
Main method to parse from a TPTP file to the data structures needed by the prover.
bool fof_conjecture_is_missing() const
Was there a conjecture clause in the problem file?
bool equality_used()
Did equality turn up anywhere in the parse?
bool conjecture_present() const
Did a conjecture turn up anywhere in the parse?
bool fof_has_axioms() const
Where there any axioms for an FOF problem before simplification?
string get_tptp_conversion_string() const
Self-explanatory.
bool fof_conjecture_is_false() const
Self-explanatory.
bool fof_conjecture_is_true() const
Self-explanatory.
Predicate * get_equals_predicate() const
If equality turned up anywhere in the parse it will have been turned into an actual Predicate,...
bool problem_is_cnf_only() const
Self-explanatory.
size_t number_of_fof_formulas() const
How many first-order formulas turned up in the parse?
bool fof_negated_conjecture_removed() const
Was there a conjecture clause that got simplified away?
General representation of terms.
Term * add_function_term(Function *, const vector< Term * > &)
Self-explanatory: add a Term containing a function to the index.
Term * add_variable_term(Variable *)
Self-explanatory: add a Term containing a variable to the index.
void backtrack()
Apply the backtracking process to the substitution that has been constructed.
Substitution get_substitution() const
Trivial get methods for the result.
Basic representation of variables.
Variable * add_named_var(const string &)
Add a variable with the specified name to the index.
void set_all_names_added()
Call this to indicate that only anonymous variables can now be created.
Simple addition of colour to strings and ostreams.
static string erase_line(uint8_t n)
void nl(uint8_t, uint8_t=1)
Full representation of inferences, beyond just the name.
LitNum Lindex
The index of the literal within the clause being used.
LitNum Lprime
The index of the literal in C_2 being used.
Substitution sigma
A copy of the substitution that makes the rule applicable. This may or may not be reusable,...
Literal L
The Literal that is used to make the inference.
ClauseNum C_2
For extensions, the number of the clause for which a fresh copy is being made.
InferenceItemType T
What kind of inference is this?
Stack items: each contains its own material for generating possible next inferences.
void set_bt_restriction_index(size_t i)
Basic set method.
void set_this_action(const InferenceItem &inf_i)
Basic set method.
Structure containing all the command line and other options.
static void set_complete_parameters()
Change the parameters to make the search complete.
static bool no_start_options()
Self-explanatory.
static void correct_missing_start_options()
Self-explanatory.
static bool search_is_complete()
Self-explanatory.