Connect++ 0.4.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
ProofPrinter.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 "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;
42 s += "{";
43 s += (item_p->c).make_LaTeX(params::sub_LaTeX_proof);
44 s += ", \\textcolor{magenta}{M}, ";
45 s += (item_p->p).make_LaTeX(params::sub_LaTeX_proof);
46 s += ", ";
47 s += (item_p->l).make_LaTeX(params::sub_LaTeX_proof);
48 s += "}\n";
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 += (item_p->sub).make_LaTeX(params::sub_LaTeX_proof);
85 s += "$}{";
86 if ((item_p->c).size() == 0)
87 s += axiom_s;
88 else
89 s += make_LaTeX_subtree(next_p);
90 s += make_LaTeX_state(item_p);
91 s += "}{";
92 /*
93 * You need to find the right subtree, which is the only thing at
94 * the same depth as you currently are.
95 */
96 right_item_p = item_p + 1;
97 while (right_item_p->depth != item_p->depth)
98 right_item_p++;
99 s += make_LaTeX_subtree(right_item_p);
100 s += "}";
101 break;
102 case StackItemType::RightBranch:
103 if ((item_p->c).size() == 0)
104 s += axiom_s;
105 else
106 s += make_LaTeX_subtree(next_p);
107 s += make_LaTeX_state(item_p);
108 break;
109 default:
110 cerr << "Something is really wrong..." << endl;
111 break;
112 }
113 return s;
114}
115//---------------------------------------------------------------------
116void ProofPrinter::make_LaTeX(const path& path_to_file,
117 const path& path_to_input_file,
118 const string& matrix_as_latex) {
119 std::ofstream file(path_to_file);
120
121 // Get the contents of the LaTeX header and transfer into the
122 // output file.
123 /*
124 std::ifstream latex_header_file(params::latex_header_file);
125 string line;
126 while (!latex_header_file.eof()) {
127 std::getline(latex_header_file, line);
128 file << line << endl;
129 }
130 latex_header_file.close();
131 */
132 file << "\\documentclass[10pt]{article}" << '\n';
133 file << "\\usepackage{libertine}" << '\n';
134 file << "\\usepackage{amsmath,amsfonts,amssymb}" << '\n';
135 file << "\\usepackage{prftree}" << '\n';
136 file << "\\usepackage{color}" << '\n';
137 file << "\\usepackage[paperwidth = 750mm, paperheight = 1500mm,landscape]{geometry}" << '\n' << '\n';
138 file << "\\begin{document}" << '\n';
139
140 // Add details of the problem.
141 file << "\\noindent\\begin{LARGE}\\textsc{Connect++}\\end{LARGE} \\\\" << endl << endl;
142 file << "\\noindent Attempting to prove problem from file: ";
143 file << "$\\mathtt{";
144 file << latex_escape_characters(path_to_input_file.filename());
145 file << "}$ \\\\" << endl << endl;
146 if (params::latex_include_matrix) {
147 file << "\\noindent Problem has matrix: " << endl << endl;
148 file << matrix_as_latex << endl;
149 }
150 file << "\\noindent\\textsc{Proof}: \\\\" << endl << endl;
151
152 if (params::latex_tiny_proof)
153 file << "\\begin{tiny}" << endl;
154
155 file << "\\[";
156
157 /*
158 * Build a LaTeX representation of the Proof.
159 */
160 if (p != nullptr) {
161 /*
162 * Start move.
163 */
164 file << "\\prftree[r]{Start}{";
165 file << make_LaTeX_subtree(&((*p)[0]));
166 file << "}{\\epsilon, \\textcolor{magenta}{M}, \\epsilon, \\epsilon}\n";
167 }
168
169 file << "\\]";
170
171 if (params::latex_tiny_proof)
172 file << "\\end{tiny}" << endl;
173
174 // Finish off the LaTeX file.
175 /*
176 std::ifstream latex_footer_file(params::latex_footer_file);
177 while (!latex_footer_file.eof()) {
178 std::getline(latex_footer_file, line);
179 file << line << '\n';
180 }
181 latex_footer_file.close();
182 */
183 file << '\n' << '\n' << "\\end{document}" << '\n';
184
185 file.close();
186
187}
188//---------------------------------------------------------------------
189void ProofPrinter::make_Prolog(const path& path_to_file) {
190 std::ofstream file(path_to_file);
191 file << "proof_stack([" << std::endl;
192 size_t s = p->size() - 1;
193 size_t i = 0;
194 for (const StackItem& si : *p) {
195 switch (si.item_type) {
196 case StackItemType::Start:
197 file << "start(";
198 file << std::to_string(si.this_action.C_2);
199 file << ")";
200 break;
201 case StackItemType::Axiom:
202 file << "axiom()";
203 break;
204 case StackItemType::Reduction:
205 file << "reduction(";
206 file << std::to_string(si.this_action.Lindex);
207 file << ", ";
208 file << std::to_string(si.this_action.index_in_path);
209 file << ")";
210 break;
211 case StackItemType::LeftBranch:
212 file << "left_branch(";
213 file << std::to_string(si.this_action.Lindex);
214 file << ", ";
215 file << std::to_string(si.this_action.C_2);
216 file << ", ";
217 file << std::to_string(si.this_action.Lprime);
218 file << ", ";
219 file << std::to_string(si.depth);
220 file << ")";
221 break;
222 case StackItemType::RightBranch:
223 file << "right_branch(";
224 file << std::to_string(si.depth);
225 file << ")";
226 break;
227 case StackItemType::Lemmata:
228 file << "lemmata(";
229 file << std::to_string(si.this_action.Lindex);
230 file << ", ";
231 file << std::to_string(si.this_action.index_in_lemmata);
232 file << ")";
233 break;
234 default:
235 cerr << "Something is really wrong..." << endl;
236 break;
237 }
238 if (i < s)
239 file << ", ";
240 file << std::endl;
241 i++;
242 }
243 file << "])." << std::endl;
244 file.close();
245}
246//---------------------------------------------------------------------
248 cout << "proof_stack([" << std::endl;
249 size_t s = p->size() - 1;
250 size_t i = 0;
251 for (const StackItem& si : *p) {
252 switch (si.item_type) {
253 case StackItemType::Start:
254 cout<< "start(";
255 cout << std::to_string(si.this_action.C_2);
256 cout << ")";
257 break;
258 case StackItemType::Axiom:
259 cout << "axiom()";
260 break;
261 case StackItemType::Reduction:
262 cout << "reduction(";
263 cout << std::to_string(si.this_action.Lindex);
264 cout << ", ";
265 cout << std::to_string(si.this_action.index_in_path);
266 cout << ")";
267 break;
268 case StackItemType::LeftBranch:
269 cout << "left_branch(";
270 cout << std::to_string(si.this_action.Lindex);
271 cout << ", ";
272 cout << std::to_string(si.this_action.C_2);
273 cout << ", ";
274 cout << std::to_string(si.this_action.Lprime);
275 cout << ", ";
276 cout << std::to_string(si.depth);
277 cout << ")";
278 break;
279 case StackItemType::RightBranch:
280 cout << "right_branch(";
281 cout << std::to_string(si.depth);
282 cout << ")";
283 break;
284 case StackItemType::Lemmata:
285 cout << "lemmata(";
286 cout << std::to_string(si.this_action.Lindex);
287 cout << ", ";
288 cout << std::to_string(si.this_action.index_in_lemmata);
289 cout << ")";
290 break;
291 default:
292 cerr << "Something is really wrong..." << endl;
293 break;
294 }
295 if (i < s)
296 cout << ", ";
297 cout << std::endl;
298 i++;
299 }
300 cout << "])." << std::endl;
301}
302//---------------------------------------------------------------------
304 cout << "cnf(proof-stack, plain, " << std::endl;
305 cout << "proof_stack(" << std::endl;
306 size_t s = p->size() - 1;
307 size_t i = 0;
308 for (const StackItem& si : *p) {
309 switch (si.item_type) {
310 case StackItemType::Start:
311 cout<< "start(";
312 cout << std::to_string(si.this_action.C_2);
313 cout << ")";
314 break;
315 case StackItemType::Axiom:
316 cout << "axiom()";
317 break;
318 case StackItemType::Reduction:
319 cout << "reduction(";
320 cout << std::to_string(si.this_action.Lindex);
321 cout << ", ";
322 cout << std::to_string(si.this_action.index_in_path);
323 cout << ")";
324 break;
325 case StackItemType::LeftBranch:
326 cout << "left_branch(";
327 cout << std::to_string(si.this_action.Lindex);
328 cout << ", ";
329 cout << std::to_string(si.this_action.C_2);
330 cout << ", ";
331 cout << std::to_string(si.this_action.Lprime);
332 cout << ", ";
333 cout << std::to_string(si.depth);
334 cout << ")";
335 break;
336 case StackItemType::RightBranch:
337 cout << "right_branch(";
338 cout << std::to_string(si.depth);
339 cout << ")";
340 break;
341 case StackItemType::Lemmata:
342 cout << "lemmata(";
343 cout << std::to_string(si.this_action.Lindex);
344 cout << ", ";
345 cout << std::to_string(si.this_action.index_in_lemmata);
346 cout << ")";
347 break;
348 default:
349 cerr << "Something is really wrong..." << endl;
350 break;
351 }
352 if (i < s)
353 cout << ", ";
354 cout << std::endl;
355 i++;
356 }
357 cout << "))." << std::endl;
358}
359//---------------------------------------------------------------------
360 vector<pair<string, vector<size_t>>> ProofPrinter::make_internal() const {
361 vector<pair<string, vector<size_t>>> out;
362
363 size_t s = p->size() - 1;
364 size_t i = 0;
365 pair<string, vector<size_t>> next_out;
366 for (const StackItem& si : *p) {
367 next_out.second.clear();
368 switch (si.item_type) {
369 case StackItemType::Start:
370 next_out.first = "start";
371 next_out.second.push_back(si.this_action.C_2);
372 out.push_back(next_out);
373 break;
374 case StackItemType::Axiom:
375 next_out.first = "axiom";
376 out.push_back(next_out);
377 break;
378 case StackItemType::Reduction:
379 next_out.first = "reduction";
380 next_out.second.push_back(si.this_action.Lindex);
381 next_out.second.push_back(si.this_action.index_in_path);
382 out.push_back(next_out);
383 break;
384 case StackItemType::LeftBranch:
385 next_out.first = "left_branch";
386 next_out.second.push_back(si.this_action.Lindex);
387 next_out.second.push_back(si.this_action.C_2);
388 next_out.second.push_back(si.this_action.Lprime);
389 next_out.second.push_back(si.depth);
390 out.push_back(next_out);
391 break;
392 case StackItemType::RightBranch:
393 next_out.first = "right_branch";
394 next_out.second.push_back(si.depth);
395 out.push_back(next_out);
396 break;
397 case StackItemType::Lemmata:
398 next_out.first = "lemmata";
399 next_out.second.push_back(si.this_action.Lindex);
400 next_out.second.push_back(si.this_action.index_in_lemmata);
401 out.push_back(next_out);
402 break;
403 default:
404 cerr << "Something is really wrong..." << endl;
405 break;
406 }
407 }
408 return out;
409}
vector< StackItem > * p
Pointer to the output of StackProver.
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.
void show_tptp()
Show the proof in a TPTP-friendly format.
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.
Stack items: each contains its own stack of possible next inferences.
Definition StackItem.hpp:51
SimplePath p
Each node in the proof tree is a tuple of clause, matrix, path, lemmata: this is the path.
Definition StackItem.hpp:65
Substitution sub
Some nodes in the proof tree have an associated substitution.
Definition StackItem.hpp:75
uint32_t depth
How deep in the proof tree are we?
Definition StackItem.hpp:88
Lemmata l
Each node in the proof tree is a tuple of clause, matrix, path, lemmata: this is the lemmata.
Definition StackItem.hpp:70
Clause c
Each node in the proof tree is a tuple of clause, matrix, path, lemmata: this is the clause.
Definition StackItem.hpp:60
StackItemType item_type
What type of StackItem is this?
Definition StackItem.hpp:55