Connect++ 0.5.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 UnificationOutcome outcome = u(neg_lit, (clauses[c_num])[l_num]);
217 if (outcome == UnificationOutcome::Succeed) {
218 result.push_back(InferenceItem(InferenceItemType::Extension, lit, ind,
219 c_num, l_num, u.get_substitution()));
220 }
221 u.backtrack();
222 }
223}
224//----------------------------------------------------------------------
225void Matrix::find_limited_extensions(Unifier& u, vector<InferenceItem>& result,
226 Clause& c, VariableIndex& var_index,
227 TermIndex& term_index) {
228 if (c.size() == 0) {
229 cerr << "You shouldn't be looking for extensions with an empty clause" << endl;
230 return;
231 }
232 find_extensions(u, result, c[0], 0, var_index, term_index);
233}
234//----------------------------------------------------------------------
235void Matrix::find_all_extensions(Unifier& u, vector<InferenceItem>& result,
236 Clause& c, VariableIndex& var_index,
237 TermIndex& term_index) {
238 if (c.size() == 0) {
239 cerr << "You shouldn't be looking for extensions with an empty clause" << endl;
240 return;
241 }
242 for (size_t index = 0; index < c.size(); index++) {
243 find_extensions(u, result, c[index], index, var_index, term_index);
244 }
245}
246//----------------------------------------------------------------------
247string Matrix::to_string() const {
248 string result;
249 colour_string::ColourString cs(params::use_colours);
250 size_t i = 0;
251 for (const Clause& c : clauses) {
252 if (is_conjecture(i))
253 result += cs("*").orange();
254 else
255 result += " ";
256 if (positive_clauses[i])
257 result += cs("+").orange();
258 else if (negative_clauses[i])
259 result += cs("-").orange();
260 else
261 result += " ";
262 result += " ";
263 i++;
264 result += c.to_string();
265 result += "\n";
266 }
267 return result;
268}
269//----------------------------------------------------------------------
270string Matrix::make_LaTeX(bool subbed) const {
271 string s ("\\[\n\\begin{split}\n");
272 s += "\\textcolor{magenta}{M} = ";
273 for (const Clause& c : clauses) {
274 s += "&\\,";
275 s += c.make_LaTeX(subbed);
276 s += "\\\\";
277 }
278 s += "\n\\end{split}\n\\]\n";
279
280 return s;
281}
282//----------------------------------------------------------------------
283void Matrix::write_to_prolog_file(const path& path_to_file) const {
284 std::ofstream file(path_to_file);
285 size_t matrix_i = 0;
286 // Nasty hack needed to stop the proof checker from printing
287 // a bunch of warnings when reading the matrix.
288 file << ":- style_check(-singleton)." << std::endl;
289 for (const Clause& c : clauses) {
290 file << "matrix(";
291 file << std::to_string(matrix_i++);
292 file << ", ";
293 file << c.to_prolog_string();
294 file << ").";
295 file << std::endl;
296 }
297 file.close();
298}
299//----------------------------------------------------------------------
300void Matrix::show_tptp() const {
301 size_t matrix_i = 0;
302 for (const Clause& c : clauses) {
303 cout << "cnf(matrix-";
304 cout << std::to_string(matrix_i++);
305 cout << ", plain, ";
306 cout << c.to_tptp_string();
307 cout << ").";
308 cout << std::endl;
309 }
310}
311//----------------------------------------------------------------------
312ostream& operator<<(ostream& out, const Matrix& m) {
313 out << "Clauses in matrix:" << endl;
314 out << "------------------" << endl;
315 size_t i = 0;
316 for (const Clause& c : m.clauses)
317 out << setw(params::output_width) << i++
318 << ": " << c << endl;
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 return out;
334}
335
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:247
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:270
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:225
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:235
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:283
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:300
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 and unique variables.
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.