Connect++ 0.6.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 file << "\\documentclass[10pt]{article}" << '\n';
122 file << "\\usepackage{libertine}" << '\n';
123 file << "\\usepackage{amsmath,amsfonts,amssymb}" << '\n';
124 file << "\\usepackage{prftree}" << '\n';
125 file << "\\usepackage{color}" << '\n';
126 file << "\\usepackage[paperwidth = 750mm, paperheight = 1500mm,landscape]{geometry}" << '\n' << '\n';
127 file << "\\begin{document}" << '\n';
128
129 // Add details of the problem.
130 file << "\\noindent\\begin{LARGE}\\textsc{Connect++}\\end{LARGE} \\\\" << endl << endl;
131 file << "\\noindent Attempting to prove problem from file: ";
132 file << "$\\mathtt{";
133 file << latex_escape_characters(path_to_input_file.filename());
134 file << "}$ \\\\" << endl << endl;
135 if (params::latex_include_matrix) {
136 file << "\\noindent Problem has matrix: " << endl << endl;
137 file << matrix_as_latex << endl;
138 }
139 file << "\\noindent\\textsc{Proof}: \\\\" << endl << endl;
140
141 if (params::latex_tiny_proof)
142 file << "\\begin{tiny}" << endl;
143
144 file << "\\[";
145
146 /*
147 * Build a LaTeX representation of the Proof.
148 */
149 if (p != nullptr) {
150 /*
151 * Start move.
152 */
153 file << "\\prftree[r]{Start}{";
154 file << make_LaTeX_subtree(&((*p)[0]));
155 file << "}{\\epsilon, \\textcolor{magenta}{M}, \\epsilon, \\epsilon}\n";
156 }
157
158 file << "\\]";
159
160 if (params::latex_tiny_proof)
161 file << "\\end{tiny}" << endl;
162
163 file << '\n' << '\n' << "\\end{document}" << '\n';
164
165 file.close();
166}
167//---------------------------------------------------------------------
168void ProofPrinter::make_Prolog(const path& path_to_file) {
169 std::ofstream file(path_to_file);
170 file << "proof_stack([" << std::endl;
171 size_t s = p->size() - 1;
172 size_t i = 0;
173 for (const StackItem& si : *p) {
174 switch (si.item_type) {
175 case StackItemType::Start:
176 file << "start(";
177 file << std::to_string(si.this_action.C_2);
178 file << ")";
179 break;
180 case StackItemType::Axiom:
181 file << "axiom()";
182 break;
183 case StackItemType::Reduction:
184 file << "reduction(";
185 file << std::to_string(si.this_action.Lindex);
186 file << ", ";
187 file << std::to_string(si.this_action.index_in_path);
188 file << ")";
189 break;
190 case StackItemType::LeftBranch:
191 file << "left_branch(";
192 file << std::to_string(si.this_action.Lindex);
193 file << ", ";
194 file << std::to_string(si.this_action.C_2);
195 file << ", ";
196 file << std::to_string(si.this_action.Lprime);
197 file << ", ";
198 file << std::to_string(si.depth);
199 file << ")";
200 break;
201 case StackItemType::RightBranch:
202 file << "right_branch(";
203 file << std::to_string(si.depth);
204 file << ")";
205 break;
206 case StackItemType::Lemmata:
207 file << "lemmata(";
208 file << std::to_string(si.this_action.Lindex);
209 file << ", ";
210 file << std::to_string(si.this_action.index_in_lemmata);
211 file << ")";
212 break;
213 default:
214 cerr << "Something is really wrong..." << endl;
215 break;
216 }
217 if (i < s)
218 file << ", ";
219 file << std::endl;
220 i++;
221 }
222 file << "])." << std::endl;
223 file.close();
224}
225//---------------------------------------------------------------------
227 cout << "proof_stack([" << std::endl;
228 size_t s = p->size() - 1;
229 size_t i = 0;
230 for (const StackItem& si : *p) {
231 switch (si.item_type) {
232 case StackItemType::Start:
233 cout<< "start(";
234 cout << std::to_string(si.this_action.C_2);
235 cout << ")";
236 break;
237 case StackItemType::Axiom:
238 cout << "axiom()";
239 break;
240 case StackItemType::Reduction:
241 cout << "reduction(";
242 cout << std::to_string(si.this_action.Lindex);
243 cout << ", ";
244 cout << std::to_string(si.this_action.index_in_path);
245 cout << ")";
246 break;
247 case StackItemType::LeftBranch:
248 cout << "left_branch(";
249 cout << std::to_string(si.this_action.Lindex);
250 cout << ", ";
251 cout << std::to_string(si.this_action.C_2);
252 cout << ", ";
253 cout << std::to_string(si.this_action.Lprime);
254 cout << ", ";
255 cout << std::to_string(si.depth);
256 cout << ")";
257 break;
258 case StackItemType::RightBranch:
259 cout << "right_branch(";
260 cout << std::to_string(si.depth);
261 cout << ")";
262 break;
263 case StackItemType::Lemmata:
264 cout << "lemmata(";
265 cout << std::to_string(si.this_action.Lindex);
266 cout << ", ";
267 cout << std::to_string(si.this_action.index_in_lemmata);
268 cout << ")";
269 break;
270 default:
271 cerr << "Something is really wrong..." << endl;
272 break;
273 }
274 if (i < s)
275 cout << ", ";
276 cout << std::endl;
277 i++;
278 }
279 cout << "])." << std::endl;
280}
281//---------------------------------------------------------------------
283 cout << "cnf(proof-stack, plain, " << std::endl;
284 cout << "proof_stack(" << std::endl;
285 size_t s = p->size() - 1;
286 size_t i = 0;
287 for (const StackItem& si : *p) {
288 switch (si.item_type) {
289 case StackItemType::Start:
290 cout<< "start(";
291 cout << std::to_string(si.this_action.C_2);
292 cout << ")";
293 break;
294 case StackItemType::Axiom:
295 cout << "axiom()";
296 break;
297 case StackItemType::Reduction:
298 cout << "reduction(";
299 cout << std::to_string(si.this_action.Lindex);
300 cout << ", ";
301 cout << std::to_string(si.this_action.index_in_path);
302 cout << ")";
303 break;
304 case StackItemType::LeftBranch:
305 cout << "left_branch(";
306 cout << std::to_string(si.this_action.Lindex);
307 cout << ", ";
308 cout << std::to_string(si.this_action.C_2);
309 cout << ", ";
310 cout << std::to_string(si.this_action.Lprime);
311 cout << ", ";
312 cout << std::to_string(si.depth);
313 cout << ")";
314 break;
315 case StackItemType::RightBranch:
316 cout << "right_branch(";
317 cout << std::to_string(si.depth);
318 cout << ")";
319 break;
320 case StackItemType::Lemmata:
321 cout << "lemmata(";
322 cout << std::to_string(si.this_action.Lindex);
323 cout << ", ";
324 cout << std::to_string(si.this_action.index_in_lemmata);
325 cout << ")";
326 break;
327 default:
328 cerr << "Something is really wrong..." << endl;
329 break;
330 }
331 if (i < s)
332 cout << ", ";
333 cout << std::endl;
334 i++;
335 }
336 cout << "))." << std::endl;
337}
338//---------------------------------------------------------------------
339 vector<pair<string, vector<size_t>>> ProofPrinter::make_internal() const {
340 vector<pair<string, vector<size_t>>> out;
341
342 size_t s = p->size() - 1;
343 size_t i = 0;
344 pair<string, vector<size_t>> next_out;
345 for (const StackItem& si : *p) {
346 next_out.second.clear();
347 switch (si.item_type) {
348 case StackItemType::Start:
349 next_out.first = "start";
350 next_out.second.push_back(si.this_action.C_2);
351 out.push_back(next_out);
352 break;
353 case StackItemType::Axiom:
354 next_out.first = "axiom";
355 out.push_back(next_out);
356 break;
357 case StackItemType::Reduction:
358 next_out.first = "reduction";
359 next_out.second.push_back(si.this_action.Lindex);
360 next_out.second.push_back(si.this_action.index_in_path);
361 out.push_back(next_out);
362 break;
363 case StackItemType::LeftBranch:
364 next_out.first = "left_branch";
365 next_out.second.push_back(si.this_action.Lindex);
366 next_out.second.push_back(si.this_action.C_2);
367 next_out.second.push_back(si.this_action.Lprime);
368 next_out.second.push_back(si.depth);
369 out.push_back(next_out);
370 break;
371 case StackItemType::RightBranch:
372 next_out.first = "right_branch";
373 next_out.second.push_back(si.depth);
374 out.push_back(next_out);
375 break;
376 case StackItemType::Lemmata:
377 next_out.first = "lemmata";
378 next_out.second.push_back(si.this_action.Lindex);
379 next_out.second.push_back(si.this_action.index_in_lemmata);
380 out.push_back(next_out);
381 break;
382 default:
383 cerr << "Something is really wrong..." << endl;
384 break;
385 }
386 }
387 return out;
388}
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 material for generating possible next inferences.
Definition StackItem.hpp:56
SimplePath p
Each node in the proof tree is a tuple of clause, matrix, path, lemmata: this is the path.
Definition StackItem.hpp:70
Substitution sub
Some nodes in the proof tree have an associated substitution.
Definition StackItem.hpp:84
uint32_t depth
How deep in the proof tree are we?
Lemmata l
Each node in the proof tree is a tuple of clause, matrix, path, lemmata: this is the lemmata.
Definition StackItem.hpp:79
Clause c
Each node in the proof tree is a tuple of clause, matrix, path, lemmata: this is the clause.
Definition StackItem.hpp:65
StackItemType item_type
What type of StackItem is this?
Definition StackItem.hpp:60