Connect++ 0.6.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
Term Class Reference

General representation of terms. More...

#include <Term.hpp>

Collaboration diagram for Term:

Public Member Functions

Variableget_v () const
 Self-explanatory access function.
 
Functionget_f () const
 Self-explanatory access function.
 
bool is_variable () const
 Self-explanatory.
 
bool is_function () const
 Self-explanatory.
 
Arity arity () const
 Self-explanatory access function.
 
Termoperator[] (size_t) const
 Access to args, but don't mess with them!
 
bool is_ground () const
 Is the term ground?
 
string to_string (bool=false, bool=false) const
 Make a string representation of the Term, taking into account any substitutions that have been made.
 
string to_prolog_string () const
 Convert to a string that can be read by Prolog.
 
string make_LaTeX (bool=false) const
 Make a useable LaTeX representation.
 
bool operator== (const Term &) const
 For the TermIndex you want strict equaliity of the data members.
 
bool is_subbed () const
 Test whether any variable has been substituted.
 
bool subbed_equal (Term *) const
 Equality test, taking substitution into account.
 
bool is_unsubbed_variable () const
 Is this a variable that hasn't been substituted?
 
bool subbed_is_function () const
 Is this term a function, taking substitution into accoumt?
 
bool subbed_is_variable () const
 Is this term a variable, taking substitution into accoumt?
 
bool contains_variable (Variable *) const
 Taking substitution into account, does the term include the variable passed?
 
Variablesubbed_variable () const
 Taking substitution into account, what variable do we actually have?
 
Functionget_subbed_f () const
 Taking substitution into account, what function do we actually have?
 
Arity get_subbed_arity () const
 Taking substitution into account, what arity do we actually have?
 
Termskip_leading_variables () const
 It may be that there is a chain of substitutions attached to a variable.
 
Termskip_leading_variables_for_unification (bool &, Variable *&, Function *&, size_t &) const
 It may be that there is a chain of substitutions attached to a variable.
 
void find_subbed_vars (set< Variable * > &) const
 Taking substitution into account, find all the variables in a term.
 
Termmake_copy_with_new_vars (VariableIndex &, TermIndex &) const
 Does as the name suggests.
 
Termmake_copy_with_new_vars_helper (VariableIndex &, TermIndex &, unordered_map< Variable *, Term * > &) const
 Main implementation of make_copy_with_new_vars.
 
set< Term * > all_variables () const
 Assuming nothing has been substituted, find all the variables in this term.
 

Private Member Functions

 Term ()
 Constructors - these are private as Terms should only ever be constructed by the TermIndex, which is a friend.
 
 Term (Variable *new_v)
 
 Term (Function *, const vector< Term * > &)
 This is the only non-trivial constructor because of the need to deal with the function arguments.
 

Private Attributes

Variablev
 
Functionf
 
vector< Term * > args
 

Friends

class TermIndex
 
ostream & operator<< (ostream &, const Term &)
 

Detailed Description

General representation of terms.

Terms can be variables or function-based. This requires care, because after you substitute the former for the latter, it effectively becomes the latter. Similarly, function-based terms are altered by substitution. If a method has "subbed" in the name it means substitutions will be taken into account.

And, yes, the OO mob want to do this with inheritance, but I don't because ultimately I want hash consing, and inheritance would stuff that up BIG TIME!

Definition at line 62 of file Term.hpp.

Constructor & Destructor Documentation

◆ Term() [1/3]

Term::Term ( )
inlineprivate

Constructors - these are private as Terms should only ever be constructed by the TermIndex, which is a friend.

Definition at line 72 of file Term.hpp.

72: v(nullptr), f(nullptr), args() {}

◆ Term() [2/3]

Term::Term ( Variable * new_v)
inlineprivate

Definition at line 73 of file Term.hpp.

73: v(new_v), f(nullptr), args() {}

◆ Term() [3/3]

Term::Term ( Function * new_f,
const vector< Term * > & new_args )
private

This is the only non-trivial constructor because of the need to deal with the function arguments.

You really should make sure you only pass arguments that were obtained from the TermIndex.

Definition at line 35 of file Term.cpp.

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}
Arity get_arity() const
Most basic access function.
Definition Function.hpp:88

Member Function Documentation

◆ all_variables()

set< Term * > Term::all_variables ( ) const

Assuming nothing has been substituted, find all the variables in this term.

Definition at line 287 of file Term.cpp.

287 {
288 set<Term*> result;
289 if (v != nullptr) {
290 if (v->is_subbed())
291 cerr << "STOP IT!!! You shouldn't be using this with substituted variables!" << endl;
292 Term* p = const_cast<Term*>(this);
293 result.insert(p);
294 }
295 else {
296 for (Term* p : args) {
297 set<Term*> some_vars = p->all_variables();
298 result.insert(some_vars.begin(), some_vars.end());
299 }
300 }
301 return result;
302}
General representation of terms.
Definition Term.hpp:62
set< Term * > all_variables() const
Assuming nothing has been substituted, find all the variables in this term.
Definition Term.cpp:287
bool is_subbed() const
Is this variable currently substituted?
Definition Variable.hpp:106

◆ arity()

Arity Term::arity ( ) const
inline

Self-explanatory access function.

Definition at line 102 of file Term.hpp.

102{ return args.size(); }

◆ contains_variable()

bool Term::contains_variable ( Variable * v2) const

Taking substitution into account, does the term include the variable passed?

Note that this acts on the eventual term, so if you look for something that has itself been subbed then the answer is "no".

Definition at line 143 of file Term.cpp.

143 {
144 if (v != nullptr)
145 return v->contains_variable(v2);
146 if (f != nullptr)
147 for (size_t i = 0; i < args.size(); i++)
148 if (args[i]->contains_variable(v2))
149 return true;
150 return false;
151}
bool contains_variable(Variable *) const
Taking substitution into account, does the term include the variable passed?
Definition Term.cpp:143
bool contains_variable(Variable *) const
Does the substitution turn the variable into something that includes the variable passed?
Definition Term.cpp:363

◆ find_subbed_vars()

void Term::find_subbed_vars ( set< Variable * > & vs) const

Taking substitution into account, find all the variables in a term.

Does not clear the parameter – you may be adding to it across a bunch of terms.

Definition at line 167 of file Term.cpp.

167 {
168 if (v != nullptr) {
169 if (v->is_subbed())
171 else
172 vs.insert(v);
173 }
174 else {
175 for (size_t i = 0; i < args.size(); i++)
176 args[i]->find_subbed_vars(vs);
177 }
178}
void find_subbed_vars(set< Variable * > &) const
Taking substitution into account, find all the variables in a term.
Definition Term.cpp:167
Term * get_subbed_term() const
Get the current substitution, or nullptr.
Definition Variable.hpp:110

◆ get_f()

Function * Term::get_f ( ) const
inline

Self-explanatory access function.

Definition at line 90 of file Term.hpp.

90{ return f; }

◆ get_subbed_arity()

Arity Term::get_subbed_arity ( ) const

Taking substitution into account, what arity do we actually have?

Definition at line 160 of file Term.cpp.

160 {
161 if (f != nullptr)
162 return f->get_arity();
163 else
164 return v->get_subbed_arity();
165}
Arity get_subbed_arity() const
If there is a chain of substitutions ending in a function, find that function's arity.
Definition Term.cpp:379

◆ get_subbed_f()

Function * Term::get_subbed_f ( ) const

Taking substitution into account, what function do we actually have?

Definition at line 153 of file Term.cpp.

153 {
154 if (f != nullptr)
155 return f;
156 else
157 return v->get_subbed_f();
158}
Function * get_subbed_f() const
If there is a chain of substitutions ending in a function, find that function.
Definition Term.cpp:370

◆ get_v()

Variable * Term::get_v ( ) const
inline

Self-explanatory access function.

Definition at line 86 of file Term.hpp.

86{ return v; }

◆ is_function()

bool Term::is_function ( ) const
inline

Self-explanatory.

Definition at line 98 of file Term.hpp.

98{ return f != nullptr; }

◆ is_ground()

bool Term::is_ground ( ) const

Is the term ground?

Do not attempt to follow substitutions.

Definition at line 72 of file Term.cpp.

72 {
73 if (v != nullptr) {
74 return false;
75 }
76 for (Term* t : args) {
77 if (!t->is_ground()) {
78 return false;
79 }
80 }
81 return true;
82}

◆ is_subbed()

bool Term::is_subbed ( ) const

Test whether any variable has been substituted.

Definition at line 58 of file Term.cpp.

58 {
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}
bool is_subbed() const
Test whether any variable has been substituted.
Definition Term.cpp:58

◆ is_unsubbed_variable()

bool Term::is_unsubbed_variable ( ) const

Is this a variable that hasn't been substituted?

Definition at line 239 of file Term.cpp.

239 {
240 if (v == nullptr)
241 return false;
242 return !(v->is_subbed());
243}

◆ is_variable()

bool Term::is_variable ( ) const
inline

Self-explanatory.

Definition at line 94 of file Term.hpp.

94{ return v != nullptr; }

◆ make_copy_with_new_vars()

Term * Term::make_copy_with_new_vars ( VariableIndex & vi,
TermIndex & ti ) const

Does as the name suggests.

Not straightforward! See documentation for make_copy_with_new_vars_helper

Implementation is in TermIndex.cpp

Parameters
viReference to the VariableIndex
tiReference to the TermIndex

Definition at line 160 of file TermIndex.cpp.

161 {
162
163 unordered_map<Variable*,Term*> v_map;
164 return make_copy_with_new_vars_helper(vi, ti, v_map);
165}
Term * make_copy_with_new_vars_helper(VariableIndex &, TermIndex &, unordered_map< Variable *, Term * > &) const
Main implementation of make_copy_with_new_vars.

◆ make_copy_with_new_vars_helper()

Term * Term::make_copy_with_new_vars_helper ( VariableIndex & vi,
TermIndex & ti,
unordered_map< Variable *, Term * > & v_map ) const

Main implementation of make_copy_with_new_vars.

Requires care. You need to build this so that the hash consing is maintained.

In general you might also need to account for substituted variables. This method removes them entirely, so you end up with a term whose only variables are new, and which are also leaves.

This needs to be maintained because the TermIndex should only ever have unsubstituted terms added. (In fact at present TermIndex doesn't make any distinction.)

It may be necessary at some point to add something that also replaces subbed variables with new ones, and additionally updates the current substitution so that they are subbed to the newly constructed terms. However, for Connection Calculus, this method is only needed with stuff in the matrix, and as variables are never directly substituted for things in the matrix the issue never arises.

Implementation is in TermIndex.cpp

Parameters
viReference to the VariableIndex
tiReference to the TermIndex
v_mapReference to an unordered_map from pointers to Variables, to pointers to Terms. Initially empty. On completion contains a map from variables, to the terms corresponding to the new variables made to replace them.

Definition at line 129 of file TermIndex.cpp.

131 {
132 Term* result = nullptr;
133 if (v != nullptr) {
134 if (v->is_subbed()) {
135 result = v->get_subbed_term()->make_copy_with_new_vars_helper(vi, ti, v_map);
136 cerr << "If you're doing Connection Calculus then something's wrong!" << endl;
137 }
138 else {
139 auto i = v_map.find(v);
140 if (i == v_map.end()) {
141 Variable* new_v = vi.add_anon_var();
142 result = ti.add_variable_term(new_v);
143 v_map.insert(VarMapType(v, result));
144 }
145 else {
146 result = i->second;
147 }
148 }
149 }
150 else {
151 vector<Term*> new_args;
152 for (size_t i = 0; i < args.size(); i++) {
153 new_args.push_back(args[i]->make_copy_with_new_vars_helper(vi, ti, v_map));
154 }
155 result = ti.add_function_term(f, new_args);
156 }
157 return result;
158}
Term * add_function_term(Function *, const vector< Term * > &)
Self-explanatory: add a Term containing a function to the index.
Definition TermIndex.cpp:56
Term * add_variable_term(Variable *)
Self-explanatory: add a Term containing a variable to the index.
Definition TermIndex.cpp:41
Basic representation of variables.
Definition Variable.hpp:58
Variable * add_anon_var()
Add an anonymous variable.

◆ make_LaTeX()

string Term::make_LaTeX ( bool subbed = false) const

Make a useable LaTeX representation.

Assumes you are in Math mode.

Parameters
subbedImplement substitutions if true

Definition at line 222 of file Term.cpp.

222 {
223 if (v != nullptr) {
224 return v->make_LaTeX(subbed);
225 }
226 string s = f->make_LaTeX();
227 if (args.size() > 0) {
228 s += "(";
229 commas::comma com(args.size());
230 for (size_t j = 0; j < args.size(); j++) {
231 s += args[j]->make_LaTeX(subbed);
232 s += com();
233 }
234 s += ")";
235 }
236 return s;
237}
string make_LaTeX() const
Make a useable LaTeX version.
Definition Function.cpp:33
string make_LaTeX(bool=false) const
Convert the Variable to a useable LaTeX representation.
Definition Term.cpp:329
Simple function object for putting commas in lists.

◆ operator==()

bool Term::operator== ( const Term & t) const

For the TermIndex you want strict equaliity of the data members.

This will not take substitutions into account.

Definition at line 44 of file Term.cpp.

44 {
45 return (v == t.v &&
46 f == t.f &&
47 args == t.args);
48}

◆ operator[]()

Term * Term::operator[] ( size_t i) const

Access to args, but don't mess with them!

Do you really need to use this? Be careful as the parameter isn't checked.

Parameters
iIndex of the argument you want.

Definition at line 50 of file Term.cpp.

50 {
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}

◆ skip_leading_variables()

Term * Term::skip_leading_variables ( ) const

It may be that there is a chain of substitutions attached to a variable.

When doing unification we actually want a pointer either to the final variable in a chain or to the first term that's a function. This returns it.

Definition at line 245 of file Term.cpp.

245 {
246 if (f == nullptr) {
247 if (v->is_subbed()) {
248 return v->skip_leading_variables();
249 }
250 }
251 Term* p = const_cast<Term*>(this);
252 return p;
253}
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:388

◆ skip_leading_variables_for_unification()

Term * Term::skip_leading_variables_for_unification ( bool & _subbed_is_var,
Variable *& _subbed_v,
Function *& _subbed_f,
size_t & _subbed_arity ) const

It may be that there is a chain of substitutions attached to a variable.

When doing unification we actually want a pointer either to the final variable in a chain or to the first term that's a function. This returns it.

In addition to what's done by skip_leading_variables, this finds some other info needed for unification, and in doing so avoids some further function calls.

Definition at line 255 of file Term.cpp.

259 {
260
261 if (f == nullptr && v == nullptr) {
262 }
263 Term* p = const_cast<Term*>(this);
264 while (p->f == nullptr) {
265 if (p->v->is_subbed()) {
266 p = p->v->get_subbed_term();
267 }
268 else {
269 break;
270 }
271 }
272 if (p->f == nullptr) {
273 _subbed_v = p->v;
274 _subbed_f = nullptr;
275 _subbed_arity = 0;
276 _subbed_is_var = true;
277 }
278 else {
279 _subbed_v = nullptr;
280 _subbed_f = p->f;
281 _subbed_arity = p->f->get_arity();
282 _subbed_is_var = false;
283 }
284 return p;
285}

◆ subbed_equal()

bool Term::subbed_equal ( Term * t) const

Equality test, taking substitution into account.

For unification you have to take substitution into account, so this needs different treatment to operator==.

Definition at line 84 of file Term.cpp.

84 {
85 if (this == t) {
86 return true;
87 }
88 Variable* tv = t->v;
89 // LHS is a variable.
90 if (v != nullptr) {
91 if (v->is_subbed()) {
92 return (v->get_subbed_term())->subbed_equal(t);
93 }
94 else if (t->subbed_is_variable()) {
95 return (t->subbed_variable() == v);
96 }
97 else return false;
98 }
99 // RHS is a variable.
100 else if (tv != nullptr) {
101 if (tv->is_subbed()) {
102 return subbed_equal(tv->get_subbed_term());
103 }
104 else return false;
105 }
106 // Both sides are functions.
107 else {
108 if (f != t->f)
109 return false;
110 if (f->get_arity() != t->f->get_arity())
111 return false;
112 for (size_t i = 0; i < f->get_arity(); i++) {
113 if (!(args[i]->subbed_equal(t->args[i])))
114 return false;
115 }
116 return true;
117 }
118}
bool subbed_equal(Term *) const
Equality test, taking substitution into account.
Definition Term.cpp:84
bool subbed_is_variable() const
Is this term a variable, taking substitution into accoumt?
Definition Term.cpp:127
Variable * subbed_variable() const
Taking substitution into account, what variable do we actually have?
Definition Term.cpp:134

◆ subbed_is_function()

bool Term::subbed_is_function ( ) const

Is this term a function, taking substitution into accoumt?

Definition at line 120 of file Term.cpp.

120 {
121 if (v == nullptr)
122 return true;
123 else
124 return v->subbed_is_function();
125}
bool subbed_is_function() const
Is the variable now a function, taking substitution into account?
Definition Term.cpp:340

◆ subbed_is_variable()

bool Term::subbed_is_variable ( ) const

Is this term a variable, taking substitution into accoumt?

Definition at line 127 of file Term.cpp.

127 {
128 if (v == nullptr)
129 return false;
130 else
131 return v->subbed_is_variable();
132}
bool subbed_is_variable() const
Is the variable still in fact a variable, taking substitution into account?
Definition Term.cpp:347

◆ subbed_variable()

Variable * Term::subbed_variable ( ) const

Taking substitution into account, what variable do we actually have?

Definition at line 134 of file Term.cpp.

134 {
135 if (f != nullptr) {
136 cerr << "You shouldn't be using this with a function term." << endl;
137 return nullptr;
138 }
139 else
140 return v->subbed_variable();
141}
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:354

◆ to_prolog_string()

string Term::to_prolog_string ( ) const

Convert to a string that can be read by Prolog.

Does not apply substitutions.

Definition at line 202 of file Term.cpp.

202 {
203 string result;
204 if (v != nullptr) {
205 result += v->get_name();
206 }
207 else if (f != nullptr) {
208 commas::comma com(args.size());
209 result += f->get_name();
210 if (args.size() > 0) {
211 result += "(";
212 for (size_t j = 0; j < args.size(); j++) {
213 result += args[j]->to_prolog_string();
214 result += com();
215 }
216 result += ")";
217 }
218 }
219 return result;
220}
string get_name() const
Most basic access function.
Definition Function.hpp:84
string get_name() const
Self-explanatory access function.
Definition Variable.hpp:96

◆ to_string()

string Term::to_string ( bool subbed = false,
bool show_addresses = false ) const

Make a string representation of the Term, taking into account any substitutions that have been made.

Parameters
subbedImplement substitutions if true
show_addressesShow memory address of this Term if true

Definition at line 180 of file Term.cpp.

180 {
181 string result;
182 if (v != nullptr) {
183 result += v->to_string(subbed);
184 }
185 else if (f != nullptr) {
186 result += f->to_string();
187 if (f->get_arity() > 0) {
188 result += vector_to_string(args, subbed, show_addresses);
189 }
190 }
191 else
192 result += "You're trying to print a badly-formed term.";
193 if (show_addresses) {
194 result += ":";
195 ostringstream oss;
196 oss << this;
197 result += oss.str();
198 }
199 return result;
200}
string to_string() const
Make a useable string representation.
Definition Function.cpp:28
string to_string(bool=false) const
Convert to a (coloured) string.
Definition Term.cpp:319

Friends And Related Symbol Documentation

◆ operator<<

ostream & operator<< ( ostream & out,
const Term & t )
friend

Definition at line 304 of file Term.cpp.

304 {
305 out << t.to_string(params::output_terms_with_substitution, true);
306 return out;
307}
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:180

◆ TermIndex

friend class TermIndex
friend

Definition at line 283 of file Term.hpp.

Member Data Documentation

◆ args

vector<Term*> Term::args
private

Definition at line 66 of file Term.hpp.

◆ f

Function* Term::f
private

Definition at line 65 of file Term.hpp.

◆ v

Variable* Term::v
private

Definition at line 64 of file Term.hpp.


The documentation for this class was generated from the following files: