Connect++ 0.7.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
Matrix.cpp
1/*
2
3Copyright © 2023-26 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, literal_clause_index((num_predicates * 2), vector<LiteralClausePairType>())
34, positive_clauses()
35, negative_clauses()
36, ground_clauses()
37, clause_roles()
38, clause_names()
39, num_equals(0)
40, clauses_copy()
41, roles_copy()
42, names_copy()
43, copy_saved(false)
44{}
45//----------------------------------------------------------------------
46void Matrix::set_num_preds(size_t num_predicates) {
47 index = vector<vector<MatrixPairType> >((num_predicates * 2), vector<MatrixPairType>());
48 literal_clause_index = vector<vector<LiteralClausePairType> >((num_predicates * 2), vector<LiteralClausePairType>());
49}
50//----------------------------------------------------------------------
51bool Matrix::is_conjecture(size_t i) const {
52 return clause_roles[i] == "negated_conjecture" ||
53 clause_roles[i] == "conjecture";
54}
55//----------------------------------------------------------------------
56pair<bool,size_t> Matrix::find_start() const {
57 bool found_positive = false;
58 bool found_negative = false;
59 size_t first_positive = 0;
60 size_t first_negative = 0;
61 bool found_candidate = false;
62 size_t candidate = 0;
63 size_t i = 0;
64 for (bool positive : positive_clauses) {
65 if (positive_clauses[i]) {
66 if (!found_positive) {
67 first_positive = i;
68 found_positive = true;
69 }
70 }
71 if (negative_clauses[i]) {
72 if (!found_negative) {
73 first_negative = i;
74 found_negative = true;
75 }
76 }
77 if (is_conjecture(i) && !found_candidate) {
78 if ((params::positive_representation && positive_clauses[i]) ||
79 (!params::positive_representation && negative_clauses[i])) {
80 found_candidate = true;
81 candidate = i;
82 }
83 }
84 i++;
85 }
86 if (!(found_positive && found_negative))
87 return pair<bool,size_t>(false, 0);
88 if (found_candidate)
89 return pair<bool, size_t>(true, candidate);
90 else if (params::positive_representation)
91 return pair<bool, size_t>(true, first_positive);
92 else
93 return pair<bool, size_t>(true, first_negative);
94}
95//----------------------------------------------------------------------
96// Note: we're assuming here that we don't have to use arity to
97// distinguish predicates.
98//----------------------------------------------------------------------
99void Matrix::add_clause(Clause& clause, string role, string name) {
100 ClauseNum clause_number = clauses.size();
101 LitNum literal_number = 0;
102 for (size_t j = 0; j < clause.size(); j++) {
103 size_t i = clause[j].get_pred_as_index();
104 index[i].push_back(MatrixPairType(clause_number, literal_number));
105 Clause new_clause = clause;
106 new_clause.drop_literal(literal_number);
107 literal_clause_index[i].push_back(LiteralClausePairType(clause[j], new_clause));
108 literal_number++;
109 }
110 clauses.push_back(clause);
111 positive_clauses.push_back(clause.is_positive());
112 negative_clauses.push_back(clause.is_negative());
113 ground_clauses.push_back(clause.is_ground());
114 clause_roles.push_back(role);
115 clause_names.push_back(name);
116}
117//----------------------------------------------------------------------
118void Matrix::rebuild_index(vector<Clause>& cs,
119 vector<string>& ss,
120 vector<string>& ns) {
121 size_t s = clauses.size();
122 clauses.clear();
123 positive_clauses.clear();
124 negative_clauses.clear();
125 ground_clauses.clear();
126 clause_roles.clear();
127 clause_names.clear();
128 size_t s2 = index.size();
129 size_t s3 = literal_clause_index.size();
130 index.clear();
131 literal_clause_index.clear();
132 index = vector<vector<MatrixPairType> >(s2, vector<MatrixPairType>());
133 literal_clause_index = vector<vector<LiteralClausePairType> >(s3, vector<LiteralClausePairType>());
134 for (size_t i = 0; i < s; i++) {
135 add_clause(cs[i], ss[i], ns[i]);
136 }
137}
138//----------------------------------------------------------------------
143 if (!copy_saved) {
144 copy_saved = true;
146 }
147 /*
148 * Find a suitably reordered set of indices.
149 */
150 vector<uint32_t> new_order;
151 size_t s = clauses.size();
152 for (size_t i = 0; i < s; i++)
153 new_order.push_back(i);
154 new_order = deterministic_reorder_n_times<uint32_t>(new_order, n);
155 /*
156 * Do the reordering.
157 */
158 vector<Clause> cs;
159 vector<string> ss;
160 vector<string> ns;
161 for (size_t i = 0; i < s; i++) {
162 size_t j = new_order[i];
163 cs.push_back(clauses_copy[j]);
164 ss.push_back(roles_copy[j]);
165 ns.push_back(names_copy[j]);
166 }
167 /*
168 * Clear and rebuild as necessary.
169 */
170 rebuild_index(cs, ss, ns);
171}
172//----------------------------------------------------------------------
174 vector<Clause> saved_clauses(clauses);
175 vector<string> saved_clause_roles(clause_roles);
176 vector<string> saved_clause_names(clause_names);
177 /*
178 * Find a suitably reordered set of indices.
179 */
180 vector<uint32_t> new_order;
181 size_t s = clauses.size();
182 for (size_t i = 0; i < s; i++)
183 new_order.push_back(i);
184 std::shuffle(new_order.begin(), new_order.end(), d);
185 /*
186 * Do the reordering.
187 */
188 vector<Clause> cs;
189 vector<string> ss;
190 vector<string> ns;
191 for (size_t i = 0; i < s; i++) {
192 size_t j = new_order[i];
193 cs.push_back(saved_clauses[j]);
194 ss.push_back(saved_clause_roles[j]);
195 ns.push_back(saved_clause_names[j]);
196 }
197 /*
198 * Clear and rebuild as necessary.
199 */
200 rebuild_index(cs, ss, ns);
201}
202//----------------------------------------------------------------------
204 vector<Clause> saved_clauses(clauses);
205 vector<string> saved_clause_roles(clause_roles);
206 vector<string> saved_clause_names(clause_names);
207 size_t s = clauses.size();
208 /*
209 * Reorder.
210 */
211 for (size_t i = 0; i < s; i++) {
212 Clause c(saved_clauses[i]);
213 c.random_reorder();
214 saved_clauses[i] = c;
215 }
216 /*
217 * Clear and rebuild as necessary.
218 */
219 rebuild_index(saved_clauses, saved_clause_roles, saved_clause_names);
220}
221//----------------------------------------------------------------------
223 if (num_equals == 0) {
224 cerr << "Why are you trying to move equality axioms - there aren't any?" << endl;
225 return;
226 }
228 clauses.clear();
229 positive_clauses.clear();
230 negative_clauses.clear();
231 ground_clauses.clear();
232 clause_roles.clear();
233 clause_names.clear();
234 size_t s2 = index.size();
235 size_t s3 = literal_clause_index.size();
236 index.clear();
237 literal_clause_index.clear();
238 index = vector<vector<MatrixPairType> >(s2, vector<MatrixPairType>());
239 literal_clause_index = vector<vector<LiteralClausePairType> >(s3, vector<LiteralClausePairType>());
240 size_t n_clauses = clauses_copy.size();
241 for (size_t i = n_clauses - num_equals; i < n_clauses; i++) {
243 }
244 for (size_t i = 0; i < n_clauses - num_equals; i++) {
246 }
247 clauses_copy.clear();
248 roles_copy.clear();
249 names_copy.clear();
250}
251//----------------------------------------------------------------------
252string Matrix::to_string() const {
253 string result;
254 colour_string::ColourString cs(params::use_colours);
255 size_t i = 0;
256 for (const Clause& c : clauses) {
257 if (is_conjecture(i))
258 result += cs("*").orange();
259 else
260 result += " ";
261 if (positive_clauses[i])
262 result += cs("+").orange();
263 else if (negative_clauses[i])
264 result += cs("-").orange();
265 else
266 result += " ";
267 result += " ";
268 result += c.to_string();
269 result += " ( ";
270 result += clause_names[i];
271 result += " )\n";
272 i++;
273 }
274 return result;
275}
276//----------------------------------------------------------------------
277string Matrix::make_LaTeX(bool subbed) const {
278 string s ("\\[\n\\begin{split}\n");
279 s += "\\textcolor{magenta}{M} = ";
280 size_t i = 0;
281 for (const Clause& c : clauses) {
282 s += std::to_string(i++);
283 s += "&:";
284 s += c.make_LaTeX(subbed);
285 s += "\\\\";
286 }
287 s += "\n\\end{split}\n\\]\n";
288
289 return s;
290}
291//----------------------------------------------------------------------
292void Matrix::write_to_prolog_file(const path& path_to_file) const {
293 std::ofstream file(path_to_file);
294 size_t matrix_i = 0;
295 // Nasty hack needed to stop the proof checker from printing
296 // a bunch of warnings when reading the matrix.
297 file << ":- style_check(-singleton)." << std::endl;
298 for (const Clause& c : clauses) {
299 file << "matrix(";
300 file << std::to_string(matrix_i++);
301 file << ", ";
302 file << c.to_prolog_string();
303 file << ").";
304 file << std::endl;
305 }
306 file.close();
307}
308//----------------------------------------------------------------------
309void Matrix::show_tptp() const {
310 size_t matrix_i = 0;
311 for (const Clause& c : clauses) {
312 cout << "cnf(matrix-";
313 cout << std::to_string(matrix_i++);
314 cout << ", plain, ";
315 cout << c.to_tptp_string();
316 cout << ").";
317 cout << std::endl;
318 }
319}
320//----------------------------------------------------------------------
321void Matrix::get_literal_clause_pair(LitNum _l, size_t _i, Literal& _lit, Clause& _clause) const {
322 LiteralClausePairType result = (literal_clause_index[_l])[_i];
323 _lit = result.first;
324 _clause = result.second;
325}
326//----------------------------------------------------------------------
328 VariableIndex& _vi, TermIndex& _ti) const {
329 _c = clauses[_index].make_copy_with_new_unique_vars(_vi, _ti);
330}
331//----------------------------------------------------------------------
332ostream& operator<<(ostream& out, const Matrix& m) {
333 out << "Clauses in matrix:" << endl;
334 out << "------------------" << endl;
335 size_t i = 0;
336 for (const Clause& c : m.clauses) {
337 out << setw(params::output_width) << i
338 << ": " << c;
339 if (m.ground_clauses[i]) {
340 out << " (ground)";
341 }
342 cout << " " << m.clause_names[i] << " " << m.clause_roles[i];
343 i++;
344 out << endl;
345 }
346 vector<string> index_lits(m.index.size(), string(""));
347 for (Clause c : m.clauses)
348 for (size_t i = 0; i < c.size(); i++)
349 index_lits[c[i].get_pred_as_index()] = c[i].get_small_lit();
350 i = 0;
351 out << endl << "Index: (Clause, Literal):" << endl;
352 out << "-------------------------" << endl;
353 for (vector<MatrixPairType> v : m.index) {
354 out << setw(params::output_width + 20) << index_lits[i++] << ": ";
355 for (MatrixPairType p : v) {
356 out << "(" << p.first << ", " << p.second << ") ";
357 }
358 out << endl;
359 }
360 out << endl << "Index: (Literal, Clause without Literal):" << endl;
361 out << "-----------------------------------------" << endl;
362 i = 0;
363 for (vector<LiteralClausePairType> v : m.literal_clause_index) {
364 out << setw(params::output_width + 20) << index_lits[i++] << ": " << endl;;
365 for (LiteralClausePairType p : v) {
366 out << p.first.to_string() << " --- " << p.second.to_string() << endl;
367 }
368 out << endl;
369 }
370 return out;
371}
372
Representation of clauses.
Definition Clause.hpp:52
void random_reorder()
Randomly re-order the literals.
Definition Clause.cpp:239
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
bool is_ground() const
Is this a ground clause?
Definition Clause.cpp:87
void drop_literal(LitNum)
Get rid of the specified Literal.
Definition Clause.cpp:168
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:74
string to_string() const
Make a string representation.
Definition Matrix.cpp:252
vector< Clause > clauses
The Matrix itself is just a set of Clauses.
Definition Matrix.hpp:79
void deterministic_reorder(size_t)
Deterministic reorder of the clauses.
Definition Matrix.cpp:139
void move_equals_to_start()
Self-explanatory.
Definition Matrix.cpp:222
vector< string > clause_names
Keep track of the names of the clauses.
Definition Matrix.hpp:108
string make_LaTeX(bool=false) const
Make a usable LaTeX representation.
Definition Matrix.cpp:277
vector< string > clause_roles
Keep track of which clauses are conjectures etc.
Definition Matrix.hpp:101
void make_clauses_copy()
Store a copy of the clauses.
Definition Matrix.hpp:153
Matrix()
Use this constructor if you really want an empty Matrix.
Definition Matrix.hpp:210
void get_literal_clause_pair(LitNum, size_t, Literal &, Clause &) const
Get a literal and clause from the index.
Definition Matrix.cpp:321
void add_clause(Clause &, string="", string="")
Add a Clause to the Matrix and update the index accordingly.
Definition Matrix.cpp:99
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:113
vector< vector< MatrixPairType > > index
We want to be able to quickly identify where in each clause a particular literal lives.
Definition Matrix.hpp:140
bool copy_saved
Remember whether you've saved a copy.
Definition Matrix.hpp:132
static std::mt19937 d
Randomness for random reordering.
Definition Matrix.hpp:149
vector< string > names_copy
It makes sense to keep a copy of the names if your schedule reorders multiple times.
Definition Matrix.hpp:128
bool is_conjecture(size_t i) const
Is a particular Clause a conjecture?
Definition Matrix.cpp:51
void make_copy_with_new_unique_vars(size_t, Clause &, VariableIndex &, TermIndex &) const
Make a new copy of a clause in the matrix.
Definition Matrix.cpp:327
vector< string > roles_copy
It makes sense to keep a copy of the roles if your schedule reorders multiple times.
Definition Matrix.hpp:123
void write_to_prolog_file(const path &) const
Write to a file that can be read by Prolog.
Definition Matrix.cpp:292
void random_reorder_literals()
Randomly reorder the literals in each clause in the matrix.
Definition Matrix.cpp:203
void rebuild_index(vector< Clause > &, vector< string > &, vector< string > &)
Rebuild the index after, for example, reordering.
Definition Matrix.cpp:118
void show_tptp() const
Output in TPTP compatible format.
Definition Matrix.cpp:309
vector< Clause > clauses_copy
It makes sense to keep a copy of the clauses if your schedule reorders multiple times.
Definition Matrix.hpp:118
void set_num_preds(size_t)
Make an empty index.
Definition Matrix.cpp:46
vector< vector< LiteralClausePairType > > literal_clause_index
This corresponds closely to index, but has the actual Literal, and the Clause after the Literal's rem...
Definition Matrix.hpp:145
pair< bool, size_t > find_start() const
Use a simple heuristic to find a good start clause.
Definition Matrix.cpp:56
void random_reorder()
Randomly reorder the matrix.
Definition Matrix.cpp:173
vector< bool > negative_clauses
Keep track of which clauses are negative.
Definition Matrix.hpp:91
vector< bool > ground_clauses
We need to know this to control backtracking.
Definition Matrix.hpp:95
vector< bool > positive_clauses
Keep track of which clauses are positive.
Definition Matrix.hpp:85
Look after terms, using hash consing to avoid storing copies of terms.
Definition TermIndex.hpp:54
Storage of named variables, and management of new, anonymous and unique variables.
Simple addition of colour to strings and ostreams.