Connect++ 0.7.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
Literal.cpp
1/*
2
3Copyright © 2023-26 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 "Literal.hpp"
26
27//----------------------------------------------------------------------
28Literal::Literal(Predicate* new_p,
29 const vector<Term*>& new_args,
30 Arity new_ar,
31 bool new_pol)
32: pred(new_p)
33, args(new_args)
34, arity(new_ar)
35, polarity(new_pol)
36{
37 #ifdef DEBUGMESSAGES
38 if (new_p == nullptr) {
39 cerr << "Why would you construct an empty predicate?" << endl;
40 }
41 #endif
42 if (new_p->get_arity() != new_args.size()) {
43 cerr << "Number of arguments doesn't match predicate arity" << endl;
44 cerr << "Are you mixing up your predicate names?" << endl;
45 }
46}
47//----------------------------------------------------------------------
49 TermIndex& ti,
50 unordered_map<Variable*,Term*>& new_vars) const {
51 vector<Term*> new_args;
52 for (size_t i = 0; i < arity; i++)
53 new_args.push_back(args[i]->make_copy_with_new_vars_helper(vi, ti, new_vars));
54 Literal result(pred, new_args, arity, polarity);
55 return result;
56}
57//----------------------------------------------------------------------
59 TermIndex& ti,
60 unordered_map<Variable*,Term*>& new_vars) const {
61 vector<Term*> new_args;
62 for (size_t i = 0; i < arity; i++)
63 new_args.push_back(args[i]->make_copy_with_new_unique_vars_helper(vi, ti, new_vars));
64 Literal result(pred, new_args, arity, polarity);
65 return result;
66}
67//----------------------------------------------------------------------
69 TermIndex& ti,
70 unordered_map<Variable*,Term*>& new_vars) {
71 for (size_t i = 0; i < arity; i++)
72 args[i] = args[i]->make_copy_with_new_vars_helper(vi, ti, new_vars);
73}
74//----------------------------------------------------------------------
76 #ifdef DEBUGMESSAGES
77 if (pred == nullptr)
78 cerr << "You shouldn't be making copies of empty Literals" << endl;
79 #endif
80 unordered_map<Variable*,Term*> new_vars;
81 return make_copy_with_new_vars_helper(vi, ti, new_vars);
82}
83//----------------------------------------------------------------------
85 #ifdef DEBUGMESSAGES
86 if (pred == nullptr || l->pred == nullptr) {
87 cerr << "You shouldn't be checking compatibility of empty Literals" << endl;
88 }
89 #endif
90 return (pred == l->pred &&
91 polarity == l->polarity &&
92 arity == l->arity);
93}
94//----------------------------------------------------------------------
95bool Literal::is_complement_of(const Literal& l) const {
96 return (pred == l.pred &&
97 args == l.args &&
98 arity == l.arity &&
99 !polarity == l.polarity);
100}
101//----------------------------------------------------------------------
102bool Literal::is_ground() const {
103 for (Term* t : args) {
104 if (!t->is_ground()) {
105 return false;
106 }
107 }
108 return true;
109}
110//----------------------------------------------------------------------
111bool Literal::is_true() const {
112 return ((polarity &&
113 (pred->get_name() == string("$true")) &&
114 (pred->get_arity() == 0))
115 ||
116 (!polarity &&
117 (pred->get_name() == string("$false")) &&
118 (pred->get_arity() == 0)));
119}
120//----------------------------------------------------------------------
121bool Literal::is_false() const {
122 return ((polarity &&
123 (pred->get_name() == string("$false")) &&
124 (pred->get_arity() == 0))
125 ||
126 (!polarity &&
127 (pred->get_name() == string("$true")) &&
128 (pred->get_arity() == 0)));
129}
130//----------------------------------------------------------------------
132 for (size_t i = 0; i < args.size(); i++) {
133 // Note that this takes account of substitutions.
134 if (args[i]->contains_variable(v))
135 return true;
136 }
137 return false;
138}
139//----------------------------------------------------------------------
140 void Literal::get_variables(set<Term*>& _vs) const {
141 for (const Term* arg : args) {
142 set<Term*> vs = arg->all_variables();
143 for (Term* v : vs) {
144 _vs.insert(v);
145 }
146 }
147 }
148//----------------------------------------------------------------------
149bool Literal::operator==(const Literal& l) const {
150 #ifdef DEBUGMESSAGES
151 if (pred == nullptr || l.pred == nullptr) {
152 cerr << "You shouldn't be checking equality of empty Literals" << endl;
153 }
154 #endif
155 return (pred == l.pred &&
156 args == l.args &&
157 arity == l.arity &&
158 polarity == l.polarity);
159}
160//----------------------------------------------------------------------
162 #ifdef DEBUGMESSAGES
163 if (pred == nullptr || l->pred == nullptr) {
164 cerr << "You shouldn't be checking subbed equality of empty Literals" << endl;
165 }
166 #endif
167 if (!is_compatible_with(l)) {
168 return false;
169 }
170 for (size_t i = 0; i < arity; i++) {
171 if (!(args[i]->subbed_equal((l->args)[i])))
172 return false;
173 }
174 return true;
175}
176//----------------------------------------------------------------------
178 string result;
179 if (!polarity)
180 result += unicode_symbols::LogSym::neg;
181 result += pred->to_string();
182 return result;
183}
184//----------------------------------------------------------------------
185string Literal::to_string(bool subbed) const {
186 string result("Empty literal");
187 if (!is_empty()) {
188 if (pred->get_name() == string("=")) {
189 result = "( ";
190 result += args[0]->to_string(subbed);
191 result += " ";
192 result += polarity ? "=" : unicode_symbols::LogSym::neq;
193 result += " ";
194 result += args[1]->to_string(subbed);
195 result += " )";
196 }
197 else {
198 result = get_small_lit();
199 result += vector_to_string(args, subbed);
200 }
201 }
202 return result;
203}
204//----------------------------------------------------------------------
206 string result;
207 if (!polarity)
208 result += "-";
209 string name = pred->get_name();
210 if (name == "=")
211 name = "equal";
212 result += name;
213 if (arity > 0) {
214 result += "(";
215 commas::comma com(args.size());
216 for (Term* p : args) {
217 result += p->to_prolog_string();
218 result += com();
219 }
220 result += ")";
221 }
222 return result;
223}
224//----------------------------------------------------------------------
225string Literal::to_tptp_string(bool subbed) const {
226 string result;
227 string name = pred->get_name();
228 if (name != "=") {
229 if (!polarity)
230 result += "~";
231 result += name;
232 if (arity > 0) {
233 result += "(";
234 commas::comma com(args.size());
235 for (Term* p : args) {
236 result += p->to_prolog_string(subbed);
237 result += com();
238 }
239 result += ")";
240 }
241 }
242 else {
243 result += args[0]->to_prolog_string(subbed);
244 if (polarity)
245 result += " = ";
246 else
247 result += " != ";
248 result += args[1]->to_prolog_string(subbed);
249 }
250 return result;
251}
252//----------------------------------------------------------------------
253string Literal::make_LaTeX(bool subbed) const {
254 string s;
255 if (!polarity)
256 s += "\\neg ";
257 s += pred->make_LaTeX();
258 if (arity > 0) {
259 s += "(";
260 commas::comma com(arity);
261 for (Term* p : args) {
262 s += p->make_LaTeX(subbed);
263 s += com();
264 }
265 s += ")";
266 }
267 return s;
268}
269//----------------------------------------------------------------------
270string Literal::make_Graphviz(bool subbed) const {
271 string s;
272 if (!polarity)
273 s += unicode_symbols::LogSym::neg;
274 s += pred->make_Graphviz();
275 if (arity > 0) {
276 s += "(";
277 commas::comma com(arity);
278 for (Term* p : args) {
279 s += p->make_Graphviz(subbed);
280 s += com();
281 }
282 s += ")";
283 }
284 return s;
285}
286//----------------------------------------------------------------------
288 TermIndex* ti) {
289#ifdef DEBUGMESSAGES
290 if (pred == nullptr)
291 cerr << "You shouldn't be replacing variables in an empty Literal" << endl;
292#endif
293 for (size_t i = 0; i < arity; i++) {
294 args[i] = ti->replace_variable_in_term(new_var, old_var, args[i]);
295 }
296}
297//----------------------------------------------------------------------
299 TermIndex* ti) {
300#ifdef DEBUGMESSAGES
301 if (pred == nullptr)
302 cerr << "You shouldn't be subbing terms in an empty Literal" << endl;
303#endif
304 for (size_t i = 0; i < arity; i++) {
305 args[i] = ti->replace_variable_in_term_with_term(new_term, old_var, args[i]);
306 }
307}
308//----------------------------------------------------------------------
309ostream& operator<<(ostream& out, const Literal& l) {
310 if (l.is_empty())
311 out << "Empty literal";
312 else {
313 if (!l.polarity)
314 out << unicode_symbols::LogSym::neg;
315 out << l.pred->to_string();
316 out << vector_to_string(l.args);
317 }
318 return out;
319}
Basic representation of literals, bundling together (pointers to) a Predicate, a collection of argume...
Definition Literal.hpp:50
bool is_false() const
Is this equivalent to $false?
Definition Literal.cpp:121
void get_variables(set< Term * > &) const
Get the variables in this literal without taking account of substitutions.
Definition Literal.cpp:140
void replace_variable_with_term(Term *, Variable *, TermIndex *)
Replace one variable with a term throughout.
Definition Literal.cpp:298
string to_string(bool=false) const
Full conversion of Literal to string.
Definition Literal.cpp:185
bool is_empty() const
Basic manipulation - entirely self-explanatory.
Definition Literal.hpp:115
string make_LaTeX(bool=false) const
Make a useable LaTeX version.
Definition Literal.cpp:253
bool contains_variable(Variable *) const
Does this Literal contain the specified variable?
Definition Literal.cpp:131
void replace_variable(Variable *, Variable *, TermIndex *)
Replace one variable with another throughout.
Definition Literal.cpp:287
bool is_complement_of(const Literal &) const
Test whether one literal is exactly the same as another, with the exception of the polarity.
Definition Literal.cpp:95
bool is_compatible_with(const Literal *) const
Literals can only be unified if the polarity and actual predicate are the same.
Definition Literal.cpp:84
void make_copy_with_new_vars_replace_helper(VariableIndex &, TermIndex &, unordered_map< Variable *, Term * > &)
Helper function for making copies with new variables.
Definition Literal.cpp:68
Literal make_copy_with_new_unique_vars_helper(VariableIndex &, TermIndex &, unordered_map< Variable *, Term * > &) const
Helper function for make_copy_with_unique_new_vars.
Definition Literal.cpp:58
Literal make_copy_with_new_vars(VariableIndex &, TermIndex &) const
Make a copy of the Literal but with a new set of variables.
Definition Literal.cpp:75
string to_tptp_string(bool=false) const
Convert to a string in a format compatible with the TPTP.
Definition Literal.cpp:225
bool operator==(const Literal &) const
Equality without taking account of substutions.
Definition Literal.cpp:149
bool is_true() const
Is this equivalent to $true?
Definition Literal.cpp:111
string get_small_lit() const
Get the predicate and polarity as a string.
Definition Literal.cpp:177
bool is_ground() const
Is the literal ground?
Definition Literal.cpp:102
bool subbed_equal(Literal *) const
Equality, taking account of substitutions.
Definition Literal.cpp:161
string make_Graphviz(bool=false) const
Make a useable Graphviz version.
Definition Literal.cpp:270
string to_prolog_string() const
Convert to a string in a format readable by Prolog.
Definition Literal.cpp:205
Literal make_copy_with_new_vars_helper(VariableIndex &, TermIndex &, unordered_map< Variable *, Term * > &) const
Helper function for make_copy_with_new_vars.
Definition Literal.cpp:48
Basic representation of predicates: here just names, ids and arities.
Definition Predicate.hpp:51
Arity get_arity() const
Basic get method.
Definition Predicate.hpp:90
string make_LaTeX() const
Make a useable LaTeX version.
Definition Predicate.cpp:36
string to_string() const
Converting to a string just gives you the name.
Definition Predicate.cpp:27
string make_Graphviz() const
Make a useable Graphviz version.
Definition Predicate.cpp:43
string get_name() const
Basic get method.
Definition Predicate.hpp:86
General representation of terms.
Definition Term.hpp:62
Look after terms, using hash consing to avoid storing copies of terms.
Definition TermIndex.hpp:54
Term * replace_variable_in_term_with_term(Term *, Variable *, Term *)
Minor variation on replace_variable_in_term.
Definition TermIndex.cpp:95
Term * replace_variable_in_term(Variable *, Variable *, Term *)
Replace a variable in a term with an alternative, maintaining the structure of the TermIndex.
Definition TermIndex.cpp:74
Basic representation of variables.
Definition Variable.hpp:58
Storage of named variables, and management of new, anonymous and unique variables.
Simple function object for putting commas in lists.