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