Connect++ 0.6.1
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
ProofPrinter.cpp
1/*
2
3Copyright © 2023-25 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 "ProofPrinter.hpp"
26
27void show_internal_proof(const ProofType& proof) {
28 size_t i = 0;
29 for (const ProofLine& line : proof) {
30 cout << "Proof step " << i << ": ";
31 cout << line.first << " (";
32 for (size_t n : line.second) {
33 cout << " " << n;
34 }
35 cout << " )" << endl;
36 i++;
37 }
38}
39//---------------------------------------------------------------------
41 string s("{\\begin{aligned}");
42 s += "C &= ";
43 s += (item_p->c).make_LaTeX(params::sub_LaTeX_proof);
44 s += "\\\\ P &= ";
45 s += (item_p->p).make_LaTeX(params::sub_LaTeX_proof);
46 s += "\\\\ L &= ";
47 s += (item_p->l).make_LaTeX(params::sub_LaTeX_proof);
48 s += "\\end{aligned}}";
49 return s;
50}
51//---------------------------------------------------------------------
53 string s;
54 string axiom_s("\\prfbyaxiom{Axiom}");
55 StackItem* next_p = item_p + 1;
56 StackItem* right_item_p;
57 switch (item_p->item_type) {
58 case StackItemType::Start:
59 s += make_LaTeX_subtree(next_p);
60 s += make_LaTeX_state(item_p);
61 break;
62 case StackItemType::Lemmata:
63 s += "\\prftree[r]{Lem}{";
64 if ((item_p->c).size() == 0)
65 s += axiom_s;
66 else
67 s += make_LaTeX_subtree(next_p);
68 s += make_LaTeX_state(item_p);
69 s += "}";
70 break;
71 case StackItemType::Reduction:
72 s += "\\prftree[r,l]{Red}{$";
73 s += (item_p->sub).make_LaTeX(params::sub_LaTeX_proof);
74 s += "$}{";
75 if ((item_p->c).size() == 0)
76 s += axiom_s;
77 else
78 s += make_LaTeX_subtree(next_p);
79 s += make_LaTeX_state(item_p);
80 s += "}";
81 break;
82 case StackItemType::LeftBranch:
83 s += "\\prftree[r,l]{Ext[";
84 s += std::to_string(item_p->this_action.C_2);
85 s += "]}{$";
86 s += (item_p->sub).make_LaTeX(params::sub_LaTeX_proof);
87 s += "$}{";
88 if ((item_p->c).size() == 0)
89 s += axiom_s;
90 else
91 s += make_LaTeX_subtree(next_p);
92 s += make_LaTeX_state(item_p);
93 s += "}{";
94 /*
95 * You need to find the right subtree, which is the only thing at
96 * the same depth as you currently are.
97 */
98 right_item_p = item_p + 1;
99 while (right_item_p->depth != item_p->depth)
100 right_item_p++;
101 s += make_LaTeX_subtree(right_item_p);
102 s += "}";
103 break;
104 case StackItemType::RightBranch:
105 if ((item_p->c).size() == 0)
106 s += axiom_s;
107 else
108 s += make_LaTeX_subtree(next_p);
109 s += make_LaTeX_state(item_p);
110 break;
111 default:
112 cerr << "Something is really wrong..." << endl;
113 break;
114 }
115 return s;
116}
117//---------------------------------------------------------------------
118void ProofPrinter::make_LaTeX(const path& path_to_file,
119 const path& path_to_input_file,
120 const string& matrix_as_latex) {
121 std::ofstream file(path_to_file);
122
123 file << "\\documentclass[10pt]{article}" << '\n';
124 file << "\\usepackage{libertine}" << '\n';
125 file << "\\usepackage{amsmath,amsfonts,amssymb}" << '\n';
126 file << "\\usepackage{prftree}" << '\n';
127 file << "\\usepackage{color}" << '\n';
128 file << "\\usepackage[paperwidth = 5000mm, paperheight = 5000mm,landscape]{geometry}" << '\n' << '\n';
129 file << "\\begin{document}" << '\n';
130
131 // Add details of the problem.
132 file << "\\noindent\\begin{LARGE}\\textsc{Connect++}\\end{LARGE} \\\\" << endl << endl;
133 file << "\\noindent Attempting to prove problem from file: ";
134 file << "$\\mathtt{";
135 file << latex_escape_characters(path_to_input_file.filename());
136 file << "}$ \\\\" << endl << endl;
137 if (params::latex_include_matrix) {
138 file << "\\noindent Problem has matrix: " << endl << endl;
139 file << matrix_as_latex << endl;
140 }
141 file << "\\noindent\\textsc{Proof}: \\\\" << endl << endl;
142
143 if (params::latex_tiny_proof)
144 file << "\\begin{tiny}" << endl;
145
146 file << "\\[";
147
148 /*
149 * Build a LaTeX representation of the Proof.
150 */
151 if (p != nullptr) {
152 /*
153 * Start move.
154 */
155 file << "\\prftree[r]{Start}{";
156 file << make_LaTeX_subtree(&((*p)[0]));
157 file << "}{\\epsilon, \\textcolor{magenta}{M}, \\epsilon, \\epsilon}\n";
158 }
159
160 file << "\\]";
161
162 if (params::latex_tiny_proof)
163 file << "\\end{tiny}" << endl;
164
165 file << '\n' << '\n' << "\\end{document}" << '\n';
166
167 file.close();
168}
169//---------------------------------------------------------------------
171 const path& path_to_input_file,
172 const string& matrix_as_latex) {
173 std::ofstream file(path_to_file);
174
175 file << "\\documentclass[10pt]{article}" << '\n';
176 file << "\\usepackage{libertine}" << '\n';
177 file << "\\usepackage{amsmath,amsfonts,amssymb}" << '\n';
178 file << "\\usepackage{forest}" << '\n';
179 file << "\\usepackage{color}" << '\n';
180 file << "\\usepackage[paperwidth = 5000mm, paperheight = 5000mm,landscape]{geometry}" << '\n' << '\n';
181 file << "\\begin{document}" << '\n';
182
183 // Add details of the problem.
184 file << "\\noindent\\begin{LARGE}\\textsc{Connect++}\\end{LARGE} \\\\" << endl << endl;
185 file << "\\noindent Attempting to prove problem from file: ";
186 file << "$\\mathtt{";
187 file << latex_escape_characters(path_to_input_file.filename());
188 file << "}$ \\\\" << endl << endl;
189 if (params::latex_include_matrix) {
190 file << "\\noindent Problem has matrix: " << endl << endl;
191 file << matrix_as_latex << endl;
192 }
193 file << "\\noindent\\textsc{Proof}: \\\\" << endl << endl;
194
195 if (params::latex_tiny_proof)
196 file << "\\begin{tiny}" << endl;
197
198 /*
199 * Build a LaTeX representation of the Proof.
200 */
201 if (p != nullptr) {
202 /*
203 * Start move.
204 */
205 file << "\\begin{forest}[Start";
206 file << '\n';
207 Clause start_clause((*p)[0].c);
208 for (const Literal& lit : start_clause) {
209 file << "[{$";
210 file << lit.make_LaTeX(params::sub_LaTeX_proof);
211 file << "$}]";
212 file << '\n';
213 }
214 file << "]\\end{forest}";
215 //file << "\\prftree[r]{Start}{";
216 //file << make_LaTeX_subtree(&((*p)[0]));
217 //file << "}{\\epsilon, \\textcolor{magenta}{M}, \\epsilon, \\epsilon}\n";
218 }
219
220 if (params::latex_tiny_proof)
221 file << "\\end{tiny}" << endl;
222
223 file << '\n' << '\n' << "\\end{document}" << '\n';
224
225 file.close();
226}
227//---------------------------------------------------------------------
228void ProofPrinter::make_Prolog(const path& path_to_file) {
229 std::ofstream file(path_to_file);
230 file << "proof_stack([" << std::endl;
231 size_t s = p->size() - 1;
232 size_t i = 0;
233 for (size_t si_index = 0; si_index < p->size(); si_index++) {
234 StackItem si((*p)[si_index]);
235 switch (si.item_type) {
236 case StackItemType::Start:
237 file << "start(";
238 file << std::to_string(si.this_action.C_2);
239 file << ")";
240 break;
241 case StackItemType::Axiom:
242 file << "axiom()";
243 break;
244 case StackItemType::Reduction:
245 file << "reduction(";
246 file << std::to_string(si.this_action.Lindex);
247 file << ", ";
248 file << std::to_string(si.this_action.index_in_path);
249 file << ")";
250 break;
251 case StackItemType::LeftBranch:
252 file << "left_branch(";
253 file << std::to_string(si.this_action.Lindex);
254 file << ", ";
255 file << std::to_string(si.this_action.C_2);
256 file << ", ";
257 file << std::to_string(si.this_action.Lprime);
258 file << ", ";
259 file << std::to_string(si.depth);
260 file << ")";
261 break;
262 case StackItemType::RightBranch:
263 file << "right_branch(";
264 file << std::to_string(si.depth);
265 file << ")";
266 break;
267 case StackItemType::Lemmata:
268 file << "lemmata(";
269 file << std::to_string(si.this_action.Lindex);
270 file << ", ";
271 file << std::to_string(si.this_action.index_in_lemmata);
272 file << ")";
273 break;
274 default:
275 cerr << "Something is really wrong..." << endl;
276 break;
277 }
278 if (i < s)
279 file << ", ";
280 file << std::endl;
281 i++;
282 }
283 file << "])." << std::endl;
284 file.close();
285}
286//---------------------------------------------------------------------
288 cout << "proof_stack([" << std::endl;
289 size_t s = p->size() - 1;
290 size_t i = 0;
291 for (size_t si_index = 0; si_index < p->size(); si_index++) {
292 StackItem si((*p)[si_index]);
293 switch (si.item_type) {
294 case StackItemType::Start:
295 cout<< "start(";
296 cout << std::to_string(si.this_action.C_2);
297 cout << ")";
298 break;
299 case StackItemType::Axiom:
300 cout << "axiom()";
301 break;
302 case StackItemType::Reduction:
303 cout << "reduction(";
304 cout << std::to_string(si.this_action.Lindex);
305 cout << ", ";
306 cout << std::to_string(si.this_action.index_in_path);
307 cout << ")";
308 break;
309 case StackItemType::LeftBranch:
310 cout << "left_branch(";
311 cout << std::to_string(si.this_action.Lindex);
312 cout << ", ";
313 cout << std::to_string(si.this_action.C_2);
314 cout << ", ";
315 cout << std::to_string(si.this_action.Lprime);
316 cout << ", ";
317 cout << std::to_string(si.depth);
318 cout << ")";
319 break;
320 case StackItemType::RightBranch:
321 cout << "right_branch(";
322 cout << std::to_string(si.depth);
323 cout << ")";
324 break;
325 case StackItemType::Lemmata:
326 cout << "lemmata(";
327 cout << std::to_string(si.this_action.Lindex);
328 cout << ", ";
329 cout << std::to_string(si.this_action.index_in_lemmata);
330 cout << ")";
331 break;
332 default:
333 cerr << "Something is really wrong..." << endl;
334 break;
335 }
336 if (i < s)
337 cout << ", ";
338 cout << std::endl;
339 i++;
340 }
341 cout << "])." << std::endl;
342}
343//---------------------------------------------------------------------
345 cout << "cnf(proof-stack, plain, " << std::endl;
346 cout << "proof_stack(" << std::endl;
347 size_t s = p->size() - 1;
348 size_t i = 0;
349 for (size_t si_index = 0; si_index < p->size(); si_index++) {
350 StackItem si((*p)[si_index]);
351 switch (si.item_type) {
352 case StackItemType::Start:
353 cout<< "start(";
354 cout << std::to_string(si.this_action.C_2);
355 cout << ")";
356 break;
357 case StackItemType::Axiom:
358 cout << "axiom()";
359 break;
360 case StackItemType::Reduction:
361 cout << "reduction(";
362 cout << std::to_string(si.this_action.Lindex);
363 cout << ", ";
364 cout << std::to_string(si.this_action.index_in_path);
365 cout << ")";
366 break;
367 case StackItemType::LeftBranch:
368 cout << "left_branch(";
369 cout << std::to_string(si.this_action.Lindex);
370 cout << ", ";
371 cout << std::to_string(si.this_action.C_2);
372 cout << ", ";
373 cout << std::to_string(si.this_action.Lprime);
374 cout << ", ";
375 cout << std::to_string(si.depth);
376 cout << ")";
377 break;
378 case StackItemType::RightBranch:
379 cout << "right_branch(";
380 cout << std::to_string(si.depth);
381 cout << ")";
382 break;
383 case StackItemType::Lemmata:
384 cout << "lemmata(";
385 cout << std::to_string(si.this_action.Lindex);
386 cout << ", ";
387 cout << std::to_string(si.this_action.index_in_lemmata);
388 cout << ")";
389 break;
390 default:
391 cerr << "Something is really wrong..." << endl;
392 break;
393 }
394 if (i < s)
395 cout << ", ";
396 cout << std::endl;
397 i++;
398 }
399 cout << "))." << std::endl;
400}
401//---------------------------------------------------------------------
402 vector<pair<string, vector<size_t>>> ProofPrinter::make_internal() const {
403 vector<pair<string, vector<size_t>>> out;
404
405 size_t s = p->size() - 1;
406 size_t i = 0;
407 pair<string, vector<size_t>> next_out;
408 for (size_t si_index = 0; si_index < p->size(); si_index++) {
409 StackItem si((*p)[si_index]);
410 next_out.second.clear();
411 switch (si.item_type) {
412 case StackItemType::Start:
413 next_out.first = "start";
414 next_out.second.push_back(si.this_action.C_2);
415 out.push_back(next_out);
416 break;
417 case StackItemType::Axiom:
418 next_out.first = "axiom";
419 out.push_back(next_out);
420 break;
421 case StackItemType::Reduction:
422 next_out.first = "reduction";
423 next_out.second.push_back(si.this_action.Lindex);
424 next_out.second.push_back(si.this_action.index_in_path);
425 out.push_back(next_out);
426 break;
427 case StackItemType::LeftBranch:
428 next_out.first = "left_branch";
429 next_out.second.push_back(si.this_action.Lindex);
430 next_out.second.push_back(si.this_action.C_2);
431 next_out.second.push_back(si.this_action.Lprime);
432 next_out.second.push_back(si.depth);
433 out.push_back(next_out);
434 break;
435 case StackItemType::RightBranch:
436 next_out.first = "right_branch";
437 next_out.second.push_back(si.depth);
438 out.push_back(next_out);
439 break;
440 case StackItemType::Lemmata:
441 next_out.first = "lemmata";
442 next_out.second.push_back(si.this_action.Lindex);
443 next_out.second.push_back(si.this_action.index_in_lemmata);
444 out.push_back(next_out);
445 break;
446 default:
447 cerr << "Something is really wrong..." << endl;
448 break;
449 }
450 }
451 return out;
452}
Representation of clauses.
Definition Clause.hpp:52
Basic representation of literals, bundling together (pointers to) a Predicate, a collection of argume...
Definition Literal.hpp:50
string make_LaTeX_state(StackItem *) const
Helper for producing LaTeX output.
void make_LaTeX_connection_tableau(const path &, const path &, const string &)
Convert to LaTeX in the connection tableau calculus and store in the specified file.
void make_Prolog(const path &)
Convert to a form suitable for use by the Prolog proof checker and write to a file.
string make_LaTeX_subtree(StackItem *) const
Helper for producing LaTeX output.
void show_tptp()
Show the proof in a TPTP-friendly format.
Stack * p
Pointer to the output of StackProver.
void make_LaTeX(const path &, const path &, const string &)
Convert to LaTeX and store in the specified file.
void show_Prolog()
Show the proof in Prolog format.
vector< pair< string, vector< size_t > > > make_internal() const
Make a simple data structure representing the proof stack.
size_t size() const
Exact analogue of the same function for vector<>.
Definition Stack.hpp:94
LitNum Lindex
The index of the literal within the clause being used.
size_t index_in_lemmata
For certification, you want to know which element of the lemmata list was used when the Lemma rule wa...
size_t index_in_path
The index in the path of the literal being used.
LitNum Lprime
The index of the literal in C_2 being used.
ClauseNum C_2
For extensions, the number of the clause for which a fresh copy is being made.
Stack items: each contains its own material for generating possible next inferences.
Definition StackItem.hpp:54
SimplePath p
Each node in the proof tree is a tuple of clause, matrix, path, lemmata: this is the path.
Definition StackItem.hpp:76
Substitution sub
Some nodes in the proof tree have an associated substitution.
Definition StackItem.hpp:94
uint32_t depth
How deep in the proof tree are we?
Definition StackItem.hpp:98
InferenceItem this_action
Action that got you to this clause, path etc.
Lemmata l
Each node in the proof tree is a tuple of clause, matrix, path, lemmas: this is the lemmas.
Definition StackItem.hpp:85
Clause c
Each node in the proof tree is a tuple of clause, matrix, path, lemmata: this is the clause.
Definition StackItem.hpp:63
StackItemType item_type
What type of StackItem is this?
Definition StackItem.hpp:58