Connect++ 0.5.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

 Term (const Term &)=delete
 
 Term (const Term &&)=delete
 
Termoperator= (const Term &)=delete
 
Termoperator= (const Term &&)=delete
 
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!
 
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.
 
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/4]

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/4]

Term::Term ( Variable * new_v)
inlineprivate

Definition at line 73 of file Term.hpp.

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

◆ Term() [3/4]

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:89

◆ Term() [4/4]

Term::Term ( const Term & )
delete

Everything you do with these should really be done via pointers, so disallow copying where you can because that would mean you're doing something wrong.

As usual, let the compiler help detect any errors.

Unfortunately it turns out that if you want to use unordered_map to hash cons Terms then you do in fact need these.

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 238 of file Term.cpp.

238 {
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}
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:238
bool is_subbed() const
Self-explanatory.
Definition Variable.hpp:111

◆ arity()

Arity Term::arity ( ) const
inline

Self-explanatory access function.

Definition at line 122 of file Term.hpp.

122{ 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 128 of file Term.cpp.

128 {
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}
bool contains_variable(Variable *) const
Taking substitution into account, does the term include the variable passed?
Definition Term.cpp:128
bool contains_variable(Variable *) const
Does the substitution turn the variable into something that includes the variable passed?
Definition Term.cpp:312

◆ 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 152 of file Term.cpp.

152 {
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}
void find_subbed_vars(set< Variable * > &) const
Taking substitution into account, find all the variables in a term.
Definition Term.cpp:152
Term * get_subbed_term() const
Self-explanatory.
Definition Variable.hpp:116

◆ get_f()

Function * Term::get_f ( ) const
inline

Self-explanatory access function.

Definition at line 110 of file Term.hpp.

110{ return f; }

◆ get_subbed_arity()

Arity Term::get_subbed_arity ( ) const

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

Definition at line 145 of file Term.cpp.

145 {
146 if (f != nullptr)
147 return f->get_arity();
148 else
149 return v->get_subbed_arity();
150}
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

◆ get_subbed_f()

Function * Term::get_subbed_f ( ) const

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

Definition at line 138 of file Term.cpp.

138 {
139 if (f != nullptr)
140 return f;
141 else
142 return v->get_subbed_f();
143}
Function * get_subbed_f() const
If there is a chain of substitutions ending in a function, find that function.
Definition Term.cpp:319

◆ get_v()

Variable * Term::get_v ( ) const
inline

Self-explanatory access function.

Definition at line 106 of file Term.hpp.

106{ return v; }

◆ is_function()

bool Term::is_function ( ) const
inline

Self-explanatory.

Definition at line 118 of file Term.hpp.

118{ return f != nullptr; }

◆ 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 222 of file Term.cpp.

222 {
223 if (v == nullptr)
224 return false;
225 return !(v->is_subbed());
226}

◆ is_variable()

bool Term::is_variable ( ) const
inline

Self-explanatory.

Definition at line 114 of file Term.hpp.

114{ 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 179 of file TermIndex.cpp.

180 {
181
182 unordered_map<Variable*,Term*> v_map;
183 return make_copy_with_new_vars_helper(vi, ti, v_map);
184}
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 148 of file TermIndex.cpp.

150 {
151 Term* result = nullptr;
152 if (v != nullptr) {
153 if (v->is_subbed()) {
154 result = v->get_subbed_term()->make_copy_with_new_vars_helper(vi, ti, v_map);
155 cerr << "If you're doing Connection Calculus then something's wrong!" << endl;
156 }
157 else {
158 auto i = v_map.find(v);
159 if (i == v_map.end()) {
160 Variable* new_v = vi.add_anon_var();
161 result = ti.add_variable_term(new_v);
162 v_map.insert(VarMapType(v, result));
163 }
164 else {
165 result = i->second;
166 }
167 }
168 }
169 else {
170 vector<Term*> new_args;
171 for (size_t i = 0; i < args.size(); i++) {
172 new_args.push_back(args[i]->make_copy_with_new_vars_helper(vi, ti, v_map));
173 }
174 result = ti.add_function_term(f, new_args);
175 }
176 return result;
177}
Term * add_function_term(Function *, const vector< Term * > &)
Self-explanatory: add a Term containing a function to the index.
Definition TermIndex.cpp:73
Term * add_variable_term(Variable *)
Self-explanatory: add a Term containing a variable to the index.
Definition TermIndex.cpp:56
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 205 of file Term.cpp.

205 {
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}
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:278
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 228 of file Term.cpp.

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

◆ 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 72 of file Term.cpp.

72 {
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}
bool subbed_equal(Term *) const
Equality test, taking substitution into account.
Definition Term.cpp:72
bool subbed_is_variable() const
Is this term a variable, taking substitution into accoumt?
Definition Term.cpp:112
Variable * subbed_variable() const
Taking substitution into account, what variable do we actually have?
Definition Term.cpp:119

◆ subbed_is_function()

bool Term::subbed_is_function ( ) const

Is this term a function, taking substitution into accoumt?

Definition at line 105 of file Term.cpp.

105 {
106 if (v == nullptr)
107 return true;
108 else
109 return v->subbed_is_function();
110}
bool subbed_is_function() const
Is the variable now a function, taking substitution into account?
Definition Term.cpp:289

◆ subbed_is_variable()

bool Term::subbed_is_variable ( ) const

Is this term a variable, taking substitution into accoumt?

Definition at line 112 of file Term.cpp.

112 {
113 if (v == nullptr)
114 return false;
115 else
116 return v->subbed_is_variable();
117}
bool subbed_is_variable() const
Is the variable still in fact a variable, taking substitution into account?
Definition Term.cpp:296

◆ subbed_variable()

Variable * Term::subbed_variable ( ) const

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

Definition at line 119 of file Term.cpp.

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

◆ 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 185 of file Term.cpp.

185 {
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}
string get_name() const
Most basic access function.
Definition Function.hpp:85
string get_name() const
Self-explanatory access function.
Definition Variable.hpp:99

◆ 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 165 of file Term.cpp.

165 {
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}
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:270

Friends And Related Symbol Documentation

◆ operator<<

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

Definition at line 255 of file Term.cpp.

255 {
256 out << t.to_string(params::output_terms_with_substitution, true);
257 return out;
258}
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

◆ TermIndex

friend class TermIndex
friend

Definition at line 83 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: