Connect++ 0.7.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
ProofPrinter.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 "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//---------------------------------------------------------------------
118string ProofPrinter::make_LaTeX_start(const path& path_to_file,
119 const path& path_to_input_file,
120 const string& matrix_as_latex) const {
121 string s("\\documentclass[10pt]{article}\n");
122 s += "\\usepackage{libertine}\n";
123 s +="\\usepackage{amsmath,amsfonts,amssymb}\n";
124 s += "\\usepackage{prftree}\n";
125 s += "\\usepackage{color}\n";
126 s += "\\usepackage{forest}\n";
127 s += "\\usepackage[paperwidth = ";
128 s += params::latex_height;
129 s += ",paperheight = ";
130 s += params::latex_width;
131 s += ",landscape]{geometry}\n\n";
132 s += "\\begin{document}\n";
133
134 // Add details of the problem.
135 s += "\\noindent\\begin{LARGE}\\textsc{Connect++}\\end{LARGE} \\\\ \n\n";
136 s += "\\noindent Attempting to prove problem from file: ";
137 s += "$\\mathtt{";
138 s += latex_escape_characters(path_to_input_file.filename());
139 s += "}$ \\\\ \n\n";
140 if (params::latex_include_matrix) {
141 s += "\\noindent Problem has matrix: \n\n";
142 s += matrix_as_latex;
143 s += "\n";
144 }
145 s += "\\noindent\\textsc{Proof}: \\\\ \n\n";
146
147 if (params::latex_tiny_proof)
148 s += "\\begin{tiny}\n";
149 return s;
150}
151//---------------------------------------------------------------------
153 string s;
154 if (params::latex_tiny_proof)
155 s += "\\end{tiny}\n";
156
157 s += "\n\n \\end{document}\n";
158 return s;
159}
160//---------------------------------------------------------------------
161void ProofPrinter::make_LaTeX(const path& path_to_file,
162 const path& path_to_input_file,
163 const string& matrix_as_latex) {
164 std::ofstream file(path_to_file);
165
166 if (!params::latex_body_only) {
167 string start = make_LaTeX_start(path_to_file,
168 path_to_input_file,
169 matrix_as_latex);
170 file << start;
171 }
172
173 file << "\\[";
174 /*
175 * Build a LaTeX representation of the Proof.
176 */
177 if (p != nullptr) {
178 /*
179 * Start move.
180 */
181 file << "\\prftree[r]{Start}{";
182 file << make_LaTeX_subtree(&((*p)[0]));
183 file << "}{\\epsilon, \\textcolor{magenta}{M}, \\epsilon, \\epsilon}\n";
184 }
185 file << "\\]";
186
187 if (!params::latex_body_only)
188 file << make_LaTeX_end();
189
190 file.close();
191}
192//---------------------------------------------------------------------
194 const path& path_to_input_file,
195 const string& matrix_as_latex,
196 Matrix* _m_p,
197 VariableIndex* _vi,
198 TermIndex* _ti) {
199
200 std::ofstream file(path_to_file);
201
202 if (!params::latex_body_only) {
203 string start = make_LaTeX_start(path_to_file,
204 path_to_input_file,
205 matrix_as_latex);
206 file << start;
207 }
208 /*
209 * Build a LaTeX representation of the Proof.
210 */
211 if (p != nullptr) {
212 TableauProof proof(p, _m_p, _vi, _ti);
213 proof.build();
214 file << proof.make_LaTeX();
215 }
216
217 if (!params::latex_body_only)
218 file << make_LaTeX_end();
219
220 file.close();
221}
222//---------------------------------------------------------------------
224 const path& problem_path,
225 Matrix* _m_p,
226 VariableIndex* _vi,
227 TermIndex* _ti) {
228
229 std::ofstream file(path_to_file);
230 /*
231 * Build a Graphviz representation of the Proof.
232 */
233 if (p != nullptr) {
234 TableauProof proof(p, _m_p, _vi, _ti);
235 proof.build();
236 file << proof.make_Graphviz(problem_path);
237 }
238 file.close();
239}
240//---------------------------------------------------------------------
241void ProofPrinter::make_Prolog(const path& path_to_file) {
242 std::ofstream file(path_to_file);
243 file << "proof_stack([" << std::endl;
244 size_t s = p->size() - 1;
245 size_t i = 0;
246 for (size_t si_index = 0; si_index < p->size(); si_index++) {
247 StackItem si((*p)[si_index]);
248 switch (si.item_type) {
249 case StackItemType::Start:
250 file << "start(";
251 file << std::to_string(si.this_action.C_2);
252 file << ")";
253 break;
254 case StackItemType::Axiom:
255 file << "axiom()";
256 break;
257 case StackItemType::Reduction:
258 file << "reduction(";
259 file << std::to_string(si.this_action.Lindex);
260 file << ", ";
261 file << std::to_string(si.this_action.index_in_path);
262 file << ")";
263 break;
264 case StackItemType::LeftBranch:
265 file << "left_branch(";
266 file << std::to_string(si.this_action.Lindex);
267 file << ", ";
268 file << std::to_string(si.this_action.C_2);
269 file << ", ";
270 file << std::to_string(si.this_action.Lprime);
271 file << ", ";
272 file << std::to_string(si.depth);
273 file << ")";
274 break;
275 case StackItemType::RightBranch:
276 file << "right_branch(";
277 file << std::to_string(si.depth);
278 file << ")";
279 break;
280 case StackItemType::Lemmata:
281 file << "lemmata(";
282 file << std::to_string(si.this_action.Lindex);
283 file << ", ";
284 file << std::to_string(si.this_action.index_in_lemmata);
285 file << ")";
286 break;
287 default:
288 cerr << "Something is really wrong..." << endl;
289 break;
290 }
291 if (i < s)
292 file << ", ";
293 file << std::endl;
294 i++;
295 }
296 file << "])." << std::endl;
297 file.close();
298}
299//---------------------------------------------------------------------
301 cout << "proof_stack([" << std::endl;
302 size_t s = p->size() - 1;
303 size_t i = 0;
304 for (size_t si_index = 0; si_index < p->size(); si_index++) {
305 StackItem si((*p)[si_index]);
306 switch (si.item_type) {
307 case StackItemType::Start:
308 cout<< "start(";
309 cout << std::to_string(si.this_action.C_2);
310 cout << ")";
311 break;
312 case StackItemType::Axiom:
313 cout << "axiom()";
314 break;
315 case StackItemType::Reduction:
316 cout << "reduction(";
317 cout << std::to_string(si.this_action.Lindex);
318 cout << ", ";
319 cout << std::to_string(si.this_action.index_in_path);
320 cout << ")";
321 break;
322 case StackItemType::LeftBranch:
323 cout << "left_branch(";
324 cout << std::to_string(si.this_action.Lindex);
325 cout << ", ";
326 cout << std::to_string(si.this_action.C_2);
327 cout << ", ";
328 cout << std::to_string(si.this_action.Lprime);
329 cout << ", ";
330 cout << std::to_string(si.depth);
331 cout << ")";
332 break;
333 case StackItemType::RightBranch:
334 cout << "right_branch(";
335 cout << std::to_string(si.depth);
336 cout << ")";
337 break;
338 case StackItemType::Lemmata:
339 cout << "lemmata(";
340 cout << std::to_string(si.this_action.Lindex);
341 cout << ", ";
342 cout << std::to_string(si.this_action.index_in_lemmata);
343 cout << ")";
344 break;
345 default:
346 cerr << "Something is really wrong..." << endl;
347 break;
348 }
349 if (i < s)
350 cout << ", ";
351 cout << std::endl;
352 i++;
353 }
354 cout << "])." << std::endl;
355}
356//---------------------------------------------------------------------
357pair<string, unordered_set<string>> ProofPrinter::make_tptp(Matrix* _m_p, VariableIndex* _vi,
358 TermIndex* _ti) {
359 TableauProof proof(p, _m_p, _vi, _ti);
360 proof.build();
361 return pair<string, unordered_set<string>>(proof.make_tptp(),
362 proof.get_clauses_used_in_proof());
363}
364//---------------------------------------------------------------------
365 vector<pair<string, vector<size_t>>> ProofPrinter::make_internal() const {
366 vector<pair<string, vector<size_t>>> out;
367
368 size_t s = p->size() - 1;
369 size_t i = 0;
370 pair<string, vector<size_t>> next_out;
371 for (size_t si_index = 0; si_index < p->size(); si_index++) {
372 StackItem si((*p)[si_index]);
373 next_out.second.clear();
374 switch (si.item_type) {
375 case StackItemType::Start:
376 next_out.first = "start";
377 next_out.second.push_back(si.this_action.C_2);
378 out.push_back(next_out);
379 break;
380 case StackItemType::Axiom:
381 next_out.first = "axiom";
382 out.push_back(next_out);
383 break;
384 case StackItemType::Reduction:
385 next_out.first = "reduction";
386 next_out.second.push_back(si.this_action.Lindex);
387 next_out.second.push_back(si.this_action.index_in_path);
388 out.push_back(next_out);
389 break;
390 case StackItemType::LeftBranch:
391 next_out.first = "left_branch";
392 next_out.second.push_back(si.this_action.Lindex);
393 next_out.second.push_back(si.this_action.C_2);
394 next_out.second.push_back(si.this_action.Lprime);
395 next_out.second.push_back(si.depth);
396 out.push_back(next_out);
397 break;
398 case StackItemType::RightBranch:
399 next_out.first = "right_branch";
400 next_out.second.push_back(si.depth);
401 out.push_back(next_out);
402 break;
403 case StackItemType::Lemmata:
404 next_out.first = "lemmata";
405 next_out.second.push_back(si.this_action.Lindex);
406 next_out.second.push_back(si.this_action.index_in_lemmata);
407 out.push_back(next_out);
408 break;
409 default:
410 cerr << "Something is really wrong..." << endl;
411 break;
412 }
413 }
414 return out;
415}
Representation of the Matrix within a proof.
Definition Matrix.hpp:74
string make_LaTeX_start(const path &, const path &, const string &) const
The beginning and end of output LaTeX files are the same for all formats.
pair< string, unordered_set< string > > make_tptp(Matrix *, VariableIndex *, TermIndex *)
Show the proof in a TPTP-friendly format.
void make_graphviz_connection_tableau(const path &, const path &, Matrix *, VariableIndex *, TermIndex *)
Convert to LaTeX in the connection tableau calculus and store in the specified file.
string make_LaTeX_state(StackItem *) const
Helper for producing LaTeX output.
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.
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.
void make_LaTeX_connection_tableau(const path &, const path &, const string &, Matrix *, VariableIndex *, TermIndex *)
Convert to LaTeX in the connection tableau calculus and store in the specified file.
string make_LaTeX_end() const
The beginning and end of output LaTeX files are the same for all formats.
size_t size() const
Exact analogue of the same function for vector<>.
Definition Stack.hpp:94
Class for representing a tableau proof in a format that allows extraction of TPTP-format proofs,...
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.
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