Connect++ 0.6.0
A fast, readable connection prover for first-order logic.
Loading...
Searching...
No Matches
Literal.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 "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) {
61 for (size_t i = 0; i < arity; i++)
62 args[i] = args[i]->make_copy_with_new_vars_helper(vi, ti, new_vars);
63}
64//----------------------------------------------------------------------
66 #ifdef DEBUGMESSAGES
67 if (pred == nullptr)
68 cerr << "You shouldn't be making copies of empty Literals" << endl;
69 #endif
70 unordered_map<Variable*,Term*> new_vars;
71 return make_copy_with_new_vars_helper(vi, ti, new_vars);
72}
73//----------------------------------------------------------------------
75 #ifdef DEBUGMESSAGES
76 if (pred == nullptr || l->pred == nullptr) {
77 cerr << "You shouldn't be checking compatibility of empty Literals" << endl;
78 }
79 #endif
80 return (pred == l->pred &&
81 polarity == l->polarity &&
82 arity == l->arity);
83}
84//----------------------------------------------------------------------
85bool Literal::is_complement_of(const Literal& l) const {
86 return (pred == l.pred &&
87 args == l.args &&
88 arity == l.arity &&
89 !polarity == l.polarity);
90}
91//----------------------------------------------------------------------
92bool Literal::is_ground() const {
93 for (Term* t : args) {
94 if (!t->is_ground()) {
95 return false;
96 }
97 }
98 return true;
99}
100//----------------------------------------------------------------------
101bool Literal::is_true() const {
102 return ((polarity &&
103 (pred->get_name() == string("$true")) &&
104 (pred->get_arity() == 0))
105 ||
106 (!polarity &&
107 (pred->get_name() == string("$false")) &&
108 (pred->get_arity() == 0)));
109}
110//----------------------------------------------------------------------
111bool Literal::is_false() const {
112 return ((polarity &&
113 (pred->get_name() == string("$false")) &&
114 (pred->get_arity() == 0))
115 ||
116 (!polarity &&
117 (pred->get_name() == string("$true")) &&
118 (pred->get_arity() == 0)));
119}
120//----------------------------------------------------------------------
122 for (size_t i = 0; i < args.size(); i++) {
123 // Note that this takes account of substitutions.
124 if (args[i]->contains_variable(v))
125 return true;
126 }
127 return false;
128}
129//----------------------------------------------------------------------
130bool Literal::operator==(const Literal& l) const {
131 #ifdef DEBUGMESSAGES
132 if (pred == nullptr || l.pred == nullptr) {
133 cerr << "You shouldn't be checking equality of empty Literals" << endl;
134 }
135 #endif
136 return (pred == l.pred &&
137 args == l.args &&
138 arity == l.arity &&
139 polarity == l.polarity);
140}
141//----------------------------------------------------------------------
143 #ifdef DEBUGMESSAGES
144 if (pred == nullptr || l->pred == nullptr) {
145 cerr << "You shouldn't be checking subbed equality of empty Literals" << endl;
146 }
147 #endif
148 if (!is_compatible_with(l)) {
149 return false;
150 }
151 for (size_t i = 0; i < arity; i++) {
152 if (!(args[i]->subbed_equal((l->args)[i])))
153 return false;
154 }
155 return true;
156}
157//----------------------------------------------------------------------
159 string result;
160 if (!polarity)
161 result += unicode_symbols::LogSym::neg;
162 result += pred->to_string();
163 return result;
164}
165//----------------------------------------------------------------------
166string Literal::to_string(bool subbed) const {
167 string result("Empty literal");
168 if (!is_empty()) {
169 if (pred->get_name() == string("=")) {
170 result = "( ";
171 result += args[0]->to_string(subbed);
172 result += " ";
173 result += polarity ? "=" : unicode_symbols::LogSym::neq;
174 result += " ";
175 result += args[1]->to_string(subbed);
176 result += " )";
177 }
178 else {
179 result = get_small_lit();
180 result += vector_to_string(args, subbed);
181 }
182 }
183 return result;
184}
185//----------------------------------------------------------------------
187 string result;
188 if (!polarity)
189 result += "-";
190 string name = pred->get_name();
191 if (name == "=")
192 name = "equal";
193 result += name;
194 if (arity > 0) {
195 result += "(";
196 commas::comma com(args.size());
197 for (Term* p : args) {
198 result += p->to_prolog_string();
199 result += com();
200 }
201 result += ")";
202 }
203 return result;
204}
205//----------------------------------------------------------------------
207 string result;
208 string name = pred->get_name();
209 if (name != "=") {
210 if (!polarity)
211 result += "~";
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 }
223 else {
224 result += "( ";
225 result += args[0]->to_prolog_string();
226 if (polarity)
227 result += " = ";
228 else
229 result += " != ";
230 result += args[1]->to_prolog_string();
231 result += ")";
232 }
233 return result;
234}
235//----------------------------------------------------------------------
236string Literal::make_LaTeX(bool subbed) const {
237 string s;
238 if (!polarity)
239 s += "\\neg ";
240 s += pred->make_LaTeX();
241 if (arity > 0) {
242 s += "(";
243 commas::comma com(arity);
244 for (Term* p : args) {
245 s += p->make_LaTeX(subbed);
246 s += com();
247 }
248 s += ")";
249 }
250 return s;
251}
252//----------------------------------------------------------------------
254 TermIndex* ti) {
255#ifdef DEBUGMESSAGES
256 if (pred == nullptr)
257 cerr << "You shouldn't be replacing variables in an empty Literal" << endl;
258#endif
259 for (size_t i = 0; i < arity; i++) {
260 args[i] = ti->replace_variable_in_term(new_var, old_var, args[i]);
261 }
262}
263//----------------------------------------------------------------------
265 TermIndex* ti) {
266#ifdef DEBUGMESSAGES
267 if (pred == nullptr)
268 cerr << "You shouldn't be subbing terms in an empty Literal" << endl;
269#endif
270 for (size_t i = 0; i < arity; i++) {
271 args[i] = ti->replace_variable_in_term_with_term(new_term, old_var, args[i]);
272 }
273}
274//----------------------------------------------------------------------
275ostream& operator<<(ostream& out, const Literal& l) {
276 if (l.is_empty())
277 out << "Empty literal";
278 else {
279 if (!l.polarity)
280 out << unicode_symbols::LogSym::neg;
281 out << l.pred->to_string();
282 out << vector_to_string(l.args);
283 }
284 return out;
285}
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:111
void replace_variable_with_term(Term *, Variable *, TermIndex *)
Replace one variable with a term throughout.
Definition Literal.cpp:264
string to_string(bool=false) const
Full conversion of Literal to string.
Definition Literal.cpp:166
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:236
bool contains_variable(Variable *) const
Does this Literal contain the specified variable?
Definition Literal.cpp:121
void replace_variable(Variable *, Variable *, TermIndex *)
Replace one variable with another throughout.
Definition Literal.cpp:253
string to_tptp_string() const
Convert to a string in a format compatible with the TPTP.
Definition Literal.cpp:206
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:85
bool is_compatible_with(const Literal *) const
Literals can only be unified if the polarity and actual predicate are the same.
Definition Literal.cpp:74
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: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:65
bool operator==(const Literal &) const
Equality without taking account of substutions.
Definition Literal.cpp:130
bool is_true() const
Is this equivalent to $true?
Definition Literal.cpp:101
string get_small_lit() const
Get the predicate and polarity as a string.
Definition Literal.cpp:158
bool is_ground() const
Is the literal ground?
Definition Literal.cpp:92
bool subbed_equal(Literal *) const
Equality, taking account of substitutions.
Definition Literal.cpp:142
string to_prolog_string() const
Convert to a string in a format readable by Prolog.
Definition Literal.cpp:186
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.