Connect++ 0.5.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
Term.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 "Term.hpp"
26
27/*
28* Some methods are in TermIndex.cpp to make the dependencies work:
29*
30* make_copy_with_new_vars_helper
31* make_copy_with_new_vars
32*/
33
34//----------------------------------------------------------------------
35Term::Term(Function* new_f, const vector<Term*>& new_args)
36: v(nullptr), f(new_f), args(new_args)
37{
38 if (new_f->get_arity() != new_args.size()) {
39 cerr << "Number of arguments doesn't match function arity" << endl;
40 cerr << "Perhaps your function names are mixed up?" << endl;
41 }
42}
43//----------------------------------------------------------------------
44bool Term::operator==(const Term& t) const {
45 return (v == t.v &&
46 f == t.f &&
47 args == t.args);
48}
49//----------------------------------------------------------------------
50Term* Term::operator[](size_t i) const {
51 if (args.size() == 0) {
52 cerr << "You shouldn't be accessing a term's arguments here." << endl;
53 return nullptr;
54 }
55 return args[i];
56}
57//----------------------------------------------------------------------
58bool Term::is_subbed() const {
59 if (v != nullptr) {
60 return v->is_subbed();
61 }
62 else {
63 for (size_t i = 0; i < args.size(); i++) {
64 if (args[i]->is_subbed()) {
65 return true;
66 }
67 }
68 }
69 return false;
70}
71//----------------------------------------------------------------------
72bool Term::subbed_equal(Term* t) const {
73 Variable* tv = t->v;
74 // LHS is a variable.
75 if (v != nullptr) {
76 if (v->is_subbed()) {
77 return (v->get_subbed_term())->subbed_equal(t);
78 }
79 else if (t->subbed_is_variable()) {
80 return (t->subbed_variable() == v);
81 }
82 else return false;
83 }
84 // RHS is a variable.
85 else if (tv != nullptr) {
86 if (tv->is_subbed()) {
87 return subbed_equal(tv->get_subbed_term());
88 }
89 else return false;
90 }
91 // Both sides are functions.
92 else {
93 if (f != t->f)
94 return false;
95 if (f->get_arity() != t->f->get_arity())
96 return false;
97 for (size_t i = 0; i < f->get_arity(); i++) {
98 if (!(args[i]->subbed_equal(t->args[i])))
99 return false;
100 }
101 return true;
102 }
103}
104//----------------------------------------------------------------------
106 if (v == nullptr)
107 return true;
108 else
109 return v->subbed_is_function();
110}
111//----------------------------------------------------------------------
113 if (v == nullptr)
114 return false;
115 else
116 return v->subbed_is_variable();
117}
118//----------------------------------------------------------------------
120 if (f != nullptr) {
121 cerr << "You shouldn't be using this with a function term." << endl;
122 return nullptr;
123 }
124 else
125 return v->subbed_variable();
126}
127//----------------------------------------------------------------------
129 if (v != nullptr)
130 return v->contains_variable(v2);
131 if (f != nullptr)
132 for (size_t i = 0; i < args.size(); i++)
133 if (args[i]->contains_variable(v2))
134 return true;
135 return false;
136}
137//----------------------------------------------------------------------
139 if (f != nullptr)
140 return f;
141 else
142 return v->get_subbed_f();
143}
144//----------------------------------------------------------------------
146 if (f != nullptr)
147 return f->get_arity();
148 else
149 return v->get_subbed_arity();
150}
151//----------------------------------------------------------------------
152void Term::find_subbed_vars(set<Variable*>& vs) const {
153 if (v != nullptr) {
154 if (v->is_subbed())
156 else
157 vs.insert(v);
158 }
159 else {
160 for (size_t i = 0; i < args.size(); i++)
161 args[i]->find_subbed_vars(vs);
162 }
163}
164//----------------------------------------------------------------------
165string Term::to_string(bool subbed, bool show_addresses) const {
166 string result;
167 if (v != nullptr) {
168 result += v->to_string(subbed);
169 }
170 else if (f != nullptr) {
171 result += f->to_string();
172 result += vector_to_string(args, subbed, show_addresses);
173 }
174 else
175 result += "You're trying to print a badly-formed term.";
176 if (show_addresses) {
177 result += ":";
178 ostringstream oss;
179 oss << this;
180 result += oss.str();
181 }
182 return result;
183}
184//----------------------------------------------------------------------
186 string result;
187 if (v != nullptr) {
188 result += v->get_name();
189 }
190 else if (f != nullptr) {
191 commas::comma com(args.size());
192 result += f->get_name();
193 if (args.size() > 0) {
194 result += "(";
195 for (size_t j = 0; j < args.size(); j++) {
196 result += args[j]->to_prolog_string();
197 result += com();
198 }
199 result += ")";
200 }
201 }
202 return result;
203}
204//----------------------------------------------------------------------
205string Term::make_LaTeX(bool subbed) const {
206 if (v != nullptr) {
207 return v->make_LaTeX(subbed);
208 }
209 string s = f->make_LaTeX();
210 if (args.size() > 0) {
211 s += "(";
212 commas::comma com(args.size());
213 for (size_t j = 0; j < args.size(); j++) {
214 s += args[j]->make_LaTeX(subbed);
215 s += com();
216 }
217 s += ")";
218 }
219 return s;
220}
221//----------------------------------------------------------------------
223 if (v == nullptr)
224 return false;
225 return !(v->is_subbed());
226}
227//----------------------------------------------------------------------
229 if (f == nullptr) {
230 if (v->is_subbed()) {
231 return v->skip_leading_variables();
232 }
233 }
234 Term* p = const_cast<Term*>(this);
235 return p;
236}
237//----------------------------------------------------------------------
238set<Term*> Term::all_variables() const {
239 set<Term*> result;
240 if (v != nullptr) {
241 if (v->is_subbed())
242 cerr << "STOP IT!!! You shouldn't be using this with substituted variables!" << endl;
243 Term* p = const_cast<Term*>(this);
244 result.insert(p);
245 }
246 else {
247 for (Term* p : args) {
248 set<Term*> some_vars = p->all_variables();
249 result.insert(some_vars.begin(), some_vars.end());
250 }
251 }
252 return result;
253}
254//----------------------------------------------------------------------
255ostream& operator<<(ostream& out, const Term& t) {
256 out << t.to_string(params::output_terms_with_substitution, true);
257 return out;
258}
259
260
261/*
262* Everything from here on is implementatin of methods for
263* Variable.hpp
264*
265* These need to be here to make the dependencies work.
266*/
267
268
269//----------------------------------------------------------------------
270string Variable::to_string(bool subbed) const {
271 colour_string::ColourString cs(params::use_colours);
272 if (!subbed || substitution == nullptr)
273 return cs(name).lblue();
274 else
275 return substitution->to_string(subbed);
276}
277//----------------------------------------------------------------------
278string Variable::make_LaTeX(bool subbed) const {
279 if (subbed && substitution != nullptr)
280 return substitution->make_LaTeX(subbed);
281 else {
282 string s ("\\text{");
283 s += latex_escape_characters(name);
284 s += "}";
285 return s;
286 }
287}
288//----------------------------------------------------------------------
290 if (substitution == nullptr)
291 return false;
292 else
293 return substitution->subbed_is_function();
294}
295//----------------------------------------------------------------------
297 if (substitution == nullptr)
298 return true;
299 else
300 return substitution->subbed_is_variable();
301}
302//----------------------------------------------------------------------
304 if (substitution == nullptr) {
305 Variable* p = const_cast<Variable*>(this);
306 return p;
307 }
308 else
309 return substitution->subbed_variable();
310}
311//----------------------------------------------------------------------
313 if (substitution == nullptr)
314 return this==v2;
315 else
316 return substitution->contains_variable(v2);
317}
318//----------------------------------------------------------------------
320 if (substitution == nullptr) {
321 cerr << "There is no function name to be found..." << endl;
322 return nullptr;
323 }
324 else
325 return substitution->get_subbed_f();
326}
327//----------------------------------------------------------------------
329 if (substitution == nullptr) {
330 cerr << "There is no arity to be found..." << endl;
331 return 0;
332 }
333 else
334 return substitution->get_subbed_arity();
335}
336//----------------------------------------------------------------------
338 if (substitution != nullptr) {
339 return substitution->skip_leading_variables();
340 }
341 cerr << "Stop it! You're trying to skip something inappropriate!" << endl;
342 return nullptr;
343}
344
Basic representation of functions.
Definition Function.hpp:54
string make_LaTeX() const
Make a useable LaTeX version.
Definition Function.cpp:33
string to_string() const
Make a useable string representation.
Definition Function.cpp:28
Arity get_arity() const
Most basic access function.
Definition Function.hpp:89
string get_name() const
Most basic access function.
Definition Function.hpp:85
General representation of terms.
Definition Term.hpp:62
Function * get_subbed_f() const
Taking substitution into account, what function do we actually have?
Definition Term.cpp:138
bool is_unsubbed_variable() const
Is this a variable that hasn't been substituted?
Definition Term.cpp:222
string make_LaTeX(bool=false) const
Make a useable LaTeX representation.
Definition Term.cpp:205
bool subbed_equal(Term *) const
Equality test, taking substitution into account.
Definition Term.cpp:72
Term * skip_leading_variables() const
It may be that there is a chain of substitutions attached to a variable.
Definition Term.cpp:228
void find_subbed_vars(set< Variable * > &) const
Taking substitution into account, find all the variables in a term.
Definition Term.cpp:152
bool subbed_is_variable() const
Is this term a variable, taking substitution into accoumt?
Definition Term.cpp:112
set< Term * > all_variables() const
Assuming nothing has been substituted, find all the variables in this term.
Definition Term.cpp:238
string to_string(bool=false, bool=false) const
Make a string representation of the Term, taking into account any substitutions that have been made.
Definition Term.cpp:165
Term()
Constructors - these are private as Terms should only ever be constructed by the TermIndex,...
Definition Term.hpp:72
Variable * subbed_variable() const
Taking substitution into account, what variable do we actually have?
Definition Term.cpp:119
Arity get_subbed_arity() const
Taking substitution into account, what arity do we actually have?
Definition Term.cpp:145
bool contains_variable(Variable *) const
Taking substitution into account, does the term include the variable passed?
Definition Term.cpp:128
bool operator==(const Term &) const
For the TermIndex you want strict equaliity of the data members.
Definition Term.cpp:44
string to_prolog_string() const
Convert to a string that can be read by Prolog.
Definition Term.cpp:185
bool is_subbed() const
Test whether any variable has been substituted.
Definition Term.cpp:58
Term * operator[](size_t) const
Access to args, but don't mess with them!
Definition Term.cpp:50
bool subbed_is_function() const
Is this term a function, taking substitution into accoumt?
Definition Term.cpp:105
Basic representation of variables.
Definition Variable.hpp:58
Variable * subbed_variable() const
If the variable is unsubbed then return "this"; otherwise a pointer to the variable at the end of a c...
Definition Term.cpp:303
Term * skip_leading_variables() const
It may be that there is a chain of substitutions attached to this variable: skip the leading ones.
Definition Term.cpp:337
bool contains_variable(Variable *) const
Does the substitution turn the variable into something that includes the variable passed?
Definition Term.cpp:312
bool subbed_is_variable() const
Is the variable still in fact a variable, taking substitution into account?
Definition Term.cpp:296
bool is_subbed() const
Self-explanatory.
Definition Variable.hpp:111
Arity get_subbed_arity() const
If there is a chain of substitutions ending in a function, find that function's arity.
Definition Term.cpp:328
Function * get_subbed_f() const
If there is a chain of substitutions ending in a function, find that function.
Definition Term.cpp:319
string to_string(bool=false) const
Convert to a (coloured) string.
Definition Term.cpp:270
bool subbed_is_function() const
Is the variable now a function, taking substitution into account?
Definition Term.cpp:289
string get_name() const
Self-explanatory access function.
Definition Variable.hpp:99
string make_LaTeX(bool=false) const
Convert the Variable to a useable LaTeX representation.
Definition Term.cpp:278
Term * get_subbed_term() const
Self-explanatory.
Definition Variable.hpp:116
Simple addition of colour to strings and ostreams.
Simple function object for putting commas in lists.