Connect++ 0.6.1
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
Literal.cpp
1/*
2
3Copyright © 2023-25 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//----------------------------------------------------------------------
140bool Literal::operator==(const Literal& l) const {
141 #ifdef DEBUGMESSAGES
142 if (pred == nullptr || l.pred == nullptr) {
143 cerr << "You shouldn't be checking equality of empty Literals" << endl;
144 }
145 #endif
146 return (pred == l.pred &&
147 args == l.args &&
148 arity == l.arity &&
149 polarity == l.polarity);
150}
151//----------------------------------------------------------------------
153 #ifdef DEBUGMESSAGES
154 if (pred == nullptr || l->pred == nullptr) {
155 cerr << "You shouldn't be checking subbed equality of empty Literals" << endl;
156 }
157 #endif
158 if (!is_compatible_with(l)) {
159 return false;
160 }
161 for (size_t i = 0; i < arity; i++) {
162 if (!(args[i]->subbed_equal((l->args)[i])))
163 return false;
164 }
165 return true;
166}
167//----------------------------------------------------------------------
169 string result;
170 if (!polarity)
171 result += unicode_symbols::LogSym::neg;
172 result += pred->to_string();
173 return result;
174}
175//----------------------------------------------------------------------
176string Literal::to_string(bool subbed) const {
177 string result("Empty literal");
178 if (!is_empty()) {
179 if (pred->get_name() == string("=")) {
180 result = "( ";
181 result += args[0]->to_string(subbed);
182 result += " ";
183 result += polarity ? "=" : unicode_symbols::LogSym::neq;
184 result += " ";
185 result += args[1]->to_string(subbed);
186 result += " )";
187 }
188 else {
189 result = get_small_lit();
190 result += vector_to_string(args, subbed);
191 }
192 }
193 return result;
194}
195//----------------------------------------------------------------------
197 string result;
198 if (!polarity)
199 result += "-";
200 string name = pred->get_name();
201 if (name == "=")
202 name = "equal";
203 result += name;
204 if (arity > 0) {
205 result += "(";
206 commas::comma com(args.size());
207 for (Term* p : args) {
208 result += p->to_prolog_string();
209 result += com();
210 }
211 result += ")";
212 }
213 return result;
214}
215//----------------------------------------------------------------------
217 string result;
218 string name = pred->get_name();
219 if (name != "=") {
220 if (!polarity)
221 result += "~";
222 result += name;
223 if (arity > 0) {
224 result += "(";
225 commas::comma com(args.size());
226 for (Term* p : args) {
227 result += p->to_prolog_string();
228 result += com();
229 }
230 result += ")";
231 }
232 }
233 else {
234 result += "( ";
235 result += args[0]->to_prolog_string();
236 if (polarity)
237 result += " = ";
238 else
239 result += " != ";
240 result += args[1]->to_prolog_string();
241 result += ")";
242 }
243 return result;
244}
245//----------------------------------------------------------------------
246string Literal::make_LaTeX(bool subbed) const {
247 string s;
248 if (!polarity)
249 s += "\\neg ";
250 s += pred->make_LaTeX();
251 if (arity > 0) {
252 s += "(";
253 commas::comma com(arity);
254 for (Term* p : args) {
255 s += p->make_LaTeX(subbed);
256 s += com();
257 }
258 s += ")";
259 }
260 return s;
261}
262//----------------------------------------------------------------------
264 TermIndex* ti) {
265#ifdef DEBUGMESSAGES
266 if (pred == nullptr)
267 cerr << "You shouldn't be replacing variables in an empty Literal" << endl;
268#endif
269 for (size_t i = 0; i < arity; i++) {
270 args[i] = ti->replace_variable_in_term(new_var, old_var, args[i]);
271 }
272}
273//----------------------------------------------------------------------
275 TermIndex* ti) {
276#ifdef DEBUGMESSAGES
277 if (pred == nullptr)
278 cerr << "You shouldn't be subbing terms in an empty Literal" << endl;
279#endif
280 for (size_t i = 0; i < arity; i++) {
281 args[i] = ti->replace_variable_in_term_with_term(new_term, old_var, args[i]);
282 }
283}
284//----------------------------------------------------------------------
285ostream& operator<<(ostream& out, const Literal& l) {
286 if (l.is_empty())
287 out << "Empty literal";
288 else {
289 if (!l.polarity)
290 out << unicode_symbols::LogSym::neg;
291 out << l.pred->to_string();
292 out << vector_to_string(l.args);
293 }
294 return out;
295}
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 replace_variable_with_term(Term *, Variable *, TermIndex *)
Replace one variable with a term throughout.
Definition Literal.cpp:274
string to_string(bool=false) const
Full conversion of Literal to string.
Definition Literal.cpp:176
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:246
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:263
string to_tptp_string() const
Convert to a string in a format compatible with the TPTP.
Definition Literal.cpp:216
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
bool operator==(const Literal &) const
Equality without taking account of substutions.
Definition Literal.cpp:140
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:168
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:152
string to_prolog_string() const
Convert to a string in a format readable by Prolog.
Definition Literal.cpp:196
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:32
string to_string() const
Converting to a string just gives you the name.
Definition Predicate.cpp:27
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.