Connect++ 0.4.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//----------------------------------------------------------------------
137 vector<Clause> saved_clauses(clauses);
138 vector<string> saved_clause_roles(clause_roles);
139 /*
140 * Find a suitably reordered set of indices.
141 */
142 vector<uint32_t> new_order;
143 size_t s = clauses.size();
144 for (size_t i = 0; i < s; i++)
145 new_order.push_back(i);
146 std::shuffle(new_order.begin(), new_order.end(), d);
147 /*
148 * Clear and rebuild as necessary.
149 */
150 clauses.clear();
151 positive_clauses.clear();
152 negative_clauses.clear();
153 clause_roles.clear();
154 size_t s2 = index.size();
155 index.clear();
156 index = vector<vector<MatrixPairType> >(s2, vector<MatrixPairType>());
157 for (size_t i = 0; i < s; i++) {
158 add_clause(saved_clauses[new_order[i]], saved_clause_roles[new_order[i]]);
159 }
160}
161//----------------------------------------------------------------------
163 vector<Clause> saved_clauses(clauses);
164 vector<string> saved_clause_roles(clause_roles);
165 size_t s = clauses.size();
166 /*
167 * Clear and rebuild as necessary, reordering as you go.
168 */
169 clauses.clear();
170 positive_clauses.clear();
171 negative_clauses.clear();
172 clause_roles.clear();
173 size_t s2 = index.size();
174 index.clear();
175 index = vector<vector<MatrixPairType> >(s2, vector<MatrixPairType>());
176 for (size_t i = 0; i < s; i++) {
177 Clause c(saved_clauses[i]);
178 c.random_reorder();
179 add_clause(c, saved_clause_roles[i]);
180 }
181}
182//----------------------------------------------------------------------
184 if (num_equals == 0) {
185 cerr << "Why are you trying to move equality axioms - there aren't any?" << endl;
186 return;
187 }
189 clauses.clear();
190 positive_clauses.clear();
191 negative_clauses.clear();
192 clause_roles.clear();
193 size_t s2 = index.size();
194 index.clear();
195 index = vector<vector<MatrixPairType> >(s2, vector<MatrixPairType>());
196 size_t n_clauses = clauses_copy.size();
197 for (size_t i = n_clauses - num_equals; i < n_clauses; i++) {
199 }
200 for (size_t i = 0; i < n_clauses - num_equals; i++) {
202 }
203 clauses_copy.clear();
204 roles_copy.clear();
205}
206//----------------------------------------------------------------------
207void Matrix::find_extensions(Unifier& u, vector<InferenceItem>& result,
208 const Literal& lit, LitNum ind,
209 VariableIndex& var_index, TermIndex& term_index) {
210 Literal neg_lit(lit);
211 neg_lit.invert();
212 size_t i = neg_lit.get_pred_as_index();
213 for (const MatrixPairType& p : index[i]) {
214 ClauseNum c_num = p.first;
215 LitNum l_num = p.second;
216 var_index.add_backtrack_point();
217 Clause new_c = (clauses[c_num]).make_copy_with_new_vars(var_index, term_index);
218 UnificationOutcome outcome = u(neg_lit, new_c[l_num]);
219 if (outcome == UnificationOutcome::Succeed) {
220 result.push_back(InferenceItem(InferenceItemType::Extension, lit, ind,
221 c_num, l_num, u.get_substitution()));
222 }
223 var_index.backtrack();
224 u.backtrack();
225 }
226}
227//----------------------------------------------------------------------
228void Matrix::find_limited_extensions(Unifier& u, vector<InferenceItem>& result,
229 Clause& c, VariableIndex& var_index,
230 TermIndex& term_index) {
231 if (c.size() == 0) {
232 cerr << "You shouldn't be looking for extensions with an empty clause" << endl;
233 return;
234 }
235 find_extensions(u, result, c[0], 0, var_index, term_index);
236}
237//----------------------------------------------------------------------
238void Matrix::find_all_extensions(Unifier& u, vector<InferenceItem>& result,
239 Clause& c, VariableIndex& var_index,
240 TermIndex& term_index) {
241 if (c.size() == 0) {
242 cerr << "You shouldn't be looking for extensions with an empty clause" << endl;
243 return;
244 }
245 for (size_t index = 0; index < c.size(); index++) {
246 find_extensions(u, result, c[index], index, var_index, term_index);
247 }
248}
249//----------------------------------------------------------------------
250string Matrix::to_string() const {
251 string result;
252 colour_string::ColourString cs(params::use_colours);
253 size_t i = 0;
254 for (const Clause& c : clauses) {
255 if (is_conjecture(i))
256 result += cs("*").orange();
257 else
258 result += " ";
259 if (positive_clauses[i])
260 result += cs("+").orange();
261 else if (negative_clauses[i])
262 result += cs("-").orange();
263 else
264 result += " ";
265 result += " ";
266 i++;
267 result += c.to_string();
268 result += "\n";
269 }
270 return result;
271}
272//----------------------------------------------------------------------
273string Matrix::make_LaTeX(bool subbed) const {
274 string s ("\\[\n\\begin{split}\n");
275 s += "\\textcolor{magenta}{M} = ";
276 for (const Clause& c : clauses) {
277 s += "&\\,";
278 s += c.make_LaTeX(subbed);
279 s += "\\\\";
280 }
281 s += "\n\\end{split}\n\\]\n";
282
283 return s;
284}
285//----------------------------------------------------------------------
286void Matrix::write_to_prolog_file(const path& path_to_file) const {
287 std::ofstream file(path_to_file);
288 size_t matrix_i = 0;
289 // Nasty hack needed to stop the proof checker from printing
290 // a bunch of warnings when reading the matrix.
291 file << ":- style_check(-singleton)." << std::endl;
292 for (const Clause& c : clauses) {
293 file << "matrix(";
294 file << std::to_string(matrix_i++);
295 file << ", ";
296 file << c.to_prolog_string();
297 file << ").";
298 file << std::endl;
299 }
300 file.close();
301}
302//----------------------------------------------------------------------
303void Matrix::show_tptp() const {
304 size_t matrix_i = 0;
305 for (const Clause& c : clauses) {
306 cout << "cnf(matrix-";
307 cout << std::to_string(matrix_i++);
308 cout << ", plain, ";
309 cout << c.to_tptp_string();
310 cout << ").";
311 cout << std::endl;
312 }
313}
314//----------------------------------------------------------------------
315ostream& operator<<(ostream& out, const Matrix& m) {
316 out << "Clauses in matrix:" << endl;
317 out << "------------------" << endl;
318 size_t i = 0;
319 for (const Clause& c : m.clauses)
320 out << setw(params::output_width) << i++
321 << ": " << c << endl;
322 vector<string> index_lits(m.index.size(), string(""));
323 for (Clause c : m.clauses)
324 for (size_t i = 0; i < c.size(); i++)
325 index_lits[c[i].get_pred_as_index()] = c[i].get_small_lit();
326 i = 0;
327 out << endl << "Index: (Clause, Literal):" << endl;
328 out << "-------------------------" << endl;
329 for (vector<MatrixPairType> v : m.index) {
330 out << setw(params::output_width + 20) << index_lits[i++] << ": ";
331 for (MatrixPairType p : v) {
332 out << "(" << p.first << ", " << p.second << ") ";
333 }
334 out << endl;
335 }
336 return out;
337}
338
Representation of clauses.
Definition Clause.hpp:52
void random_reorder()
Randomly re-order the literals.
Definition Clause.cpp:188
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:73
string to_string() const
Make a string representation.
Definition Matrix.cpp:250
vector< Clause > clauses
The Matrix itself is just a set of Clauses.
Definition Matrix.hpp:78
void deterministic_reorder(size_t)
Deterministic reorder of the clauses.
Definition Matrix.cpp:105
void move_equals_to_start()
Self-explanatory.
Definition Matrix.cpp:183
string make_LaTeX(bool=false) const
Make a usable LaTeX representation.
Definition Matrix.cpp:273
vector< string > clause_roles
Keep track of which clauses are conjectures etc.
Definition Matrix.hpp:96
void make_clauses_copy()
Store a copy of the clauses.
Definition Matrix.hpp:152
void find_extensions(Unifier &, vector< InferenceItem > &, const Literal &, LitNum, VariableIndex &, TermIndex &)
Find all possible extensions, given a Literal.
Definition Matrix.cpp:207
Matrix()
Use this constructor if you really want an empty Matrix.
Definition Matrix.hpp:198
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:101
vector< vector< MatrixPairType > > index
We want to be able to quickly identify where in each clause a particular literal lives.
Definition Matrix.hpp:123
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:228
bool copy_saved
Remember whether you've saved a copy.
Definition Matrix.hpp:115
static std::mt19937 d
Randomness for random reordering.
Definition Matrix.hpp:127
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:238
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:111
void write_to_prolog_file(const path &) const
Write to a file that can be read by Prolog.
Definition Matrix.cpp:286
void random_reorder_literals()
Randomly reorder the literals in each clause in the matrix.
Definition Matrix.cpp:162
void show_tptp() const
Output in TPTP compatible format.
Definition Matrix.cpp:303
vector< Clause > clauses_copy
It makes sense to keep a copy of the clauses if your schedule reorders multiple times.
Definition Matrix.hpp:106
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:90
vector< bool > positive_clauses
Keep track of which clauses are positive.
Definition Matrix.hpp:84
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.