Connect++ 0.3.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
Matrix.cpp
1/*
2
3Copyright © 2023-24 Sean Holden. All rights reserved.
4
5*/
6/*
7
8This file is part of Connect++.
9
10Connect++ is free software: you can redistribute it and/or modify it
11under the terms of the GNU General Public License as published by the
12Free Software Foundation, either version 3 of the License, or (at your
13option) any later version.
14
15Connect++ is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18more details.
19
20You should have received a copy of the GNU General Public License along
21with Connect++. If not, see <https://www.gnu.org/licenses/>.
22
23*/
24
25#include "Matrix.hpp"
26
27std::mt19937 Matrix::d(params::random_seed);
28
29//----------------------------------------------------------------------
30Matrix::Matrix(size_t num_predicates)
31: clauses()
32, index((num_predicates * 2), vector<MatrixPairType>())
33, positive_clauses()
34, negative_clauses()
35, clause_roles()
36, num_equals(0)
37, clauses_copy()
38, roles_copy()
39, copy_saved(false)
40{}
41//----------------------------------------------------------------------
42void Matrix::set_num_preds(size_t num_predicates) {
43 index = vector<vector<MatrixPairType> >((num_predicates * 2), vector<MatrixPairType>());
44}
45//----------------------------------------------------------------------
46bool Matrix::is_conjecture(size_t i) const {
47 return clause_roles[i] == "negated_conjecture" ||
48 clause_roles[i] == "conjecture";
49}
50//----------------------------------------------------------------------
51pair<bool,size_t> Matrix::find_start() const {
52 bool found_positive = false;
53 bool found_negative = false;
54 size_t first_positive = 0;
55 size_t first_negative = 0;
56 bool found_candidate = false;
57 size_t candidate = 0;
58 size_t i = 0;
59 for (bool positive : positive_clauses) {
60 if (positive_clauses[i]) {
61 if (!found_positive) {
62 first_positive = i;
63 found_positive = true;
64 }
65 }
66 if (negative_clauses[i]) {
67 if (!found_negative) {
68 first_negative = i;
69 found_negative = true;
70 }
71 }
72 if (is_conjecture(i) && !found_candidate) {
73 if ((params::positive_representation && positive_clauses[i]) ||
74 (!params::positive_representation && negative_clauses[i])) {
75 found_candidate = true;
76 candidate = i;
77 }
78 }
79 i++;
80 }
81 if (!(found_positive && found_negative))
82 return pair<bool,size_t>(false, 0);
83 if (found_candidate)
84 return pair<bool, size_t>(true, candidate);
85 else if (params::positive_representation)
86 return pair<bool, size_t>(true, first_positive);
87 else
88 return pair<bool, size_t>(true, first_negative);
89}
90//----------------------------------------------------------------------
91void Matrix::add_clause(Clause& clause, string role) {
92 ClauseNum clause_number = clauses.size();
93 LitNum literal_number = 0;
94 for (size_t j = 0; j < clause.size(); j++) {
95 size_t i = clause[j].get_pred_as_index();
96 index[i].push_back(MatrixPairType(clause_number, literal_number));
97 literal_number++;
98 }
99 clauses.push_back(clause);
100 positive_clauses.push_back(clause.is_positive());
101 negative_clauses.push_back(clause.is_negative());
102 clause_roles.push_back(role);
103}
104//----------------------------------------------------------------------
109 if (!copy_saved) {
110 copy_saved = true;
112 }
113 /*
114 * Find a suitably reordered set of indices.
115 */
116 vector<uint32_t> new_order;
117 size_t s = clauses.size();
118 for (size_t i = 0; i < s; i++)
119 new_order.push_back(i);
120 new_order = deterministic_reorder_n_times<uint32_t>(new_order, n);
121 /*
122 * Clear and rebuild as necessary.
123 */
124 clauses.clear();
125 positive_clauses.clear();
126 negative_clauses.clear();
127 clause_roles.clear();
128 size_t s2 = index.size();
129 index.clear();
130 index = vector<vector<MatrixPairType> >(s2, vector<MatrixPairType>());
131 for (size_t i = 0; i < s; i++) {
132 add_clause(clauses_copy[new_order[i]], roles_copy[new_order[i]]);
133 }
134}
135//----------------------------------------------------------------------
140 if (!copy_saved) {
141 copy_saved = true;
143 }
144 /*
145 * Find a suitably reordered set of indices.
146 */
147 vector<uint32_t> new_order;
148 size_t s = clauses.size();
149 for (size_t i = 0; i < s; i++)
150 new_order.push_back(i);
151 std::shuffle(new_order.begin(), new_order.end(), d);
152 /*
153 * Clear and rebuild as necessary.
154 */
155 clauses.clear();
156 positive_clauses.clear();
157 negative_clauses.clear();
158 clause_roles.clear();
159 size_t s2 = index.size();
160 index.clear();
161 index = vector<vector<MatrixPairType> >(s2, vector<MatrixPairType>());
162 for (size_t i = 0; i < s; i++) {
163 add_clause(clauses_copy[new_order[i]], roles_copy[new_order[i]]);
164 }
165}
166//----------------------------------------------------------------------
168 if (num_equals == 0) {
169 cerr << "Why are you trying to move equality axioms - there aren't any?" << endl;
170 return;
171 }
173 clauses.clear();
174 positive_clauses.clear();
175 negative_clauses.clear();
176 clause_roles.clear();
177 size_t s2 = index.size();
178 index.clear();
179 index = vector<vector<MatrixPairType> >(s2, vector<MatrixPairType>());
180 size_t n_clauses = clauses_copy.size();
181 for (size_t i = n_clauses - num_equals; i < n_clauses; i++) {
183 }
184 for (size_t i = 0; i < n_clauses - num_equals; i++) {
186 }
187 clauses_copy.clear();
188 roles_copy.clear();
189}
190//----------------------------------------------------------------------
191void Matrix::find_extensions(Unifier& u, vector<InferenceItem>& result,
192 const Literal& lit, LitNum ind,
193 VariableIndex& var_index, TermIndex& term_index) {
194 Literal neg_lit(lit);
195 neg_lit.invert();
196 size_t i = neg_lit.get_pred_as_index();
197 for (const MatrixPairType& p : index[i]) {
198 ClauseNum c_num = p.first;
199 LitNum l_num = p.second;
200 var_index.add_backtrack_point();
201 Clause new_c = (clauses[c_num]).make_copy_with_new_vars(var_index, term_index);
202 UnificationOutcome outcome = u(neg_lit, new_c[l_num]);
203 if (outcome == UnificationOutcome::Succeed) {
204 result.push_back(InferenceItem(InferenceItemType::Extension, lit, ind,
205 c_num, l_num, u.get_substitution()));
206 }
207 var_index.backtrack();
208 u.backtrack();
209 }
210}
211//----------------------------------------------------------------------
212void Matrix::find_limited_extensions(Unifier& u, vector<InferenceItem>& result,
213 Clause& c, VariableIndex& var_index,
214 TermIndex& term_index) {
215 if (c.size() == 0) {
216 cerr << "You shouldn't be looking for extensions with an empty clause" << endl;
217 return;
218 }
219 find_extensions(u, result, c[0], 0, var_index, term_index);
220}
221//----------------------------------------------------------------------
222void Matrix::find_all_extensions(Unifier& u, vector<InferenceItem>& result,
223 Clause& c, VariableIndex& var_index,
224 TermIndex& term_index) {
225 if (c.size() == 0) {
226 cerr << "You shouldn't be looking for extensions with an empty clause" << endl;
227 return;
228 }
229 for (size_t index = 0; index < c.size(); index++) {
230 find_extensions(u, result, c[index], index, var_index, term_index);
231 }
232}
233//----------------------------------------------------------------------
234string Matrix::to_string() const {
235 string result;
236 colour_string::ColourString cs(params::use_colours);
237 size_t i = 0;
238 for (const Clause& c : clauses) {
239 if (is_conjecture(i))
240 result += cs("*").orange();
241 else
242 result += " ";
243 if (positive_clauses[i])
244 result += cs("+").orange();
245 else if (negative_clauses[i])
246 result += cs("-").orange();
247 else
248 result += " ";
249 result += " ";
250 i++;
251 result += c.to_string();
252 result += "\n";
253 }
254 return result;
255}
256//----------------------------------------------------------------------
257string Matrix::make_LaTeX(bool subbed) const {
258 string s ("\\[\n\\begin{split}\n");
259 s += "\\textcolor{magenta}{M} = ";
260 for (const Clause& c : clauses) {
261 s += "&\\,";
262 s += c.make_LaTeX(subbed);
263 s += "\\\\";
264 }
265 s += "\n\\end{split}\n\\]\n";
266
267 return s;
268}
269//----------------------------------------------------------------------
270void Matrix::write_to_prolog_file(const path& path_to_file) const {
271 std::ofstream file(path_to_file);
272 size_t matrix_i = 0;
273 // Nasty hack needed to stop the proof checker from printing
274 // a bunch of warnings when reading the matrix.
275 file << ":- style_check(-singleton)." << std::endl;
276 for (const Clause& c : clauses) {
277 file << "matrix(";
278 file << std::to_string(matrix_i++);
279 file << ", ";
280 file << c.to_prolog_string();
281 file << ").";
282 file << std::endl;
283 }
284 file.close();
285}
286//----------------------------------------------------------------------
287void Matrix::show_tptp() const {
288 size_t matrix_i = 0;
289 for (const Clause& c : clauses) {
290 cout << "cnf(matrix-";
291 cout << std::to_string(matrix_i++);
292 cout << ", plain, ";
293 cout << c.to_tptp_string();
294 cout << ").";
295 cout << std::endl;
296 }
297}
298//----------------------------------------------------------------------
299ostream& operator<<(ostream& out, const Matrix& m) {
300 out << "Clauses in matrix:" << endl;
301 out << "------------------" << endl;
302 size_t i = 0;
303 for (const Clause& c : m.clauses)
304 out << setw(params::output_width) << i++
305 << ": " << c << endl;
306 vector<string> index_lits(m.index.size(), string(""));
307 for (Clause c : m.clauses)
308 for (size_t i = 0; i < c.size(); i++)
309 index_lits[c[i].get_pred_as_index()] = c[i].get_small_lit();
310 i = 0;
311 out << endl << "Index: (Clause, Literal):" << endl;
312 out << "-------------------------" << endl;
313 for (vector<MatrixPairType> v : m.index) {
314 out << setw(params::output_width + 20) << index_lits[i++] << ": ";
315 for (MatrixPairType p : v) {
316 out << "(" << p.first << ", " << p.second << ") ";
317 }
318 out << endl;
319 }
320 return out;
321}
322
Representation of clauses.
Definition Clause.hpp:52
bool is_positive() const
A clause is positive if it has no negated literals.
Definition Clause.cpp:30
size_t size() const
Straightforward get method.
Definition Clause.hpp:78
bool is_negative() const
A clause is negative if it has only negated literals.
Definition Clause.cpp:42
Basic representation of literals, bundling together (pointers to) a Predicate, a collection of argume...
Definition Literal.hpp:50
Representation of the Matrix within a proof.
Definition Matrix.hpp:72
string to_string() const
Make a string representation.
Definition Matrix.cpp:234
vector< Clause > clauses
The Matrix itself is just a set of Clauses.
Definition Matrix.hpp:77
void deterministic_reorder(size_t)
Deterministic reorder of the clauses.
Definition Matrix.cpp:105
void move_equals_to_start()
Self-explanatory.
Definition Matrix.cpp:167
string make_LaTeX(bool=false) const
Make a usable LaTeX representation.
Definition Matrix.cpp:257
vector< string > clause_roles
Keep track of which clauses are conjectures etc.
Definition Matrix.hpp:95
void make_clauses_copy()
Store a copy of the clauses.
Definition Matrix.hpp:151
void find_extensions(Unifier &, vector< InferenceItem > &, const Literal &, LitNum, VariableIndex &, TermIndex &)
Find all possible extensions, given a Literal.
Definition Matrix.cpp:191
Matrix()
Use this constructor if you really want an empty Matrix.
Definition Matrix.hpp:162
uint32_t num_equals
You need to know how many equality axioms there are in case you want to move them around.
Definition Matrix.hpp:100
vector< vector< MatrixPairType > > index
We want to be able to quickly identify where in each clause a particular literal lives.
Definition Matrix.hpp:122
void add_clause(Clause &, string="")
Add a Clause to the Matrix and update the index accordingly.
Definition Matrix.cpp:91
void find_limited_extensions(Unifier &, vector< InferenceItem > &, Clause &, VariableIndex &, TermIndex &)
Find all possible extensions given a Clause, but only consider the first Literal in the Clause.
Definition Matrix.cpp:212
bool copy_saved
Remember whether you've saved a copy.
Definition Matrix.hpp:114
static std::mt19937 d
Randomness for random reordering.
Definition Matrix.hpp:126
void find_all_extensions(Unifier &, vector< InferenceItem > &, Clause &, VariableIndex &, TermIndex &)
Find all possible extensions given a Clause, considering all Literals in the Clause.
Definition Matrix.cpp:222
bool is_conjecture(size_t i) const
Is a particular Clause a conjecture?
Definition Matrix.cpp:46
vector< string > roles_copy
It makes sense to keep a copy of the roles if your schedule reorders multiple times.
Definition Matrix.hpp:110
void write_to_prolog_file(const path &) const
Write to a file that can be read by Prolog.
Definition Matrix.cpp:270
void show_tptp() const
Output in TPTP compatible format.
Definition Matrix.cpp:287
vector< Clause > clauses_copy
It makes sense to keep a copy of the clauses if your schedule reorders multiple times.
Definition Matrix.hpp:105
void set_num_preds(size_t)
Make an empty index.
Definition Matrix.cpp:42
pair< bool, size_t > find_start() const
Use a simple heuristic to find a good start clause.
Definition Matrix.cpp:51
void random_reorder()
Randomly reorder the matrix.
Definition Matrix.cpp:136
vector< bool > negative_clauses
Keep track of which clauses are negative.
Definition Matrix.hpp:89
vector< bool > positive_clauses
Keep track of which clauses are positive.
Definition Matrix.hpp:83
Look after terms, (ideally) using hash consing to avoid storing copies of terms.
Definition TermIndex.hpp:75
Wrap up various applications of unificiation into a single class: all the unification you need to do ...
Definition Unifier.hpp:83
void backtrack()
Apply the backtracking process to the substitution that has been constructed.
Definition Unifier.cpp:134
Substitution get_substitution() const
Trivial get methods for the result.
Definition Unifier.hpp:116
Storage of named variables, and management of new, anonymous variables.
void backtrack()
Backtrack to the last marker.
void add_backtrack_point()
Add a backtrack point.
Simple addition of colour to strings and ostreams.
Full representation of inferences, beyond just the name.
Structure containing all the command line and other options.