@@ -160,12 +160,6 @@ class Expr:
160
160
(3) (x % y) and (x ^ y).
161
161
It is very ugly to have (x % y) mean (x <=> y), but we need
162
162
SOME operator to make (2) work, and this seems the best choice.
163
-
164
- WARNING: if x is an Expr, then so is x + 1, because the int 1 gets
165
- coerced to an Expr by the constructor. But 1 + x is an error, because
166
- 1 doesn't know how to add an Expr. (Adding an __radd__ method to Expr
167
- wouldn't help, because int.__add__ is still called first.) Therefore,
168
- you should use Expr(1) + x instead, or ONE + x, or expr('1 + x').
169
163
"""
170
164
171
165
def __init__ (self , op , * args ):
@@ -216,6 +210,8 @@ def __gt__(self, other): return Expr('>', self, other)
216
210
217
211
def __add__ (self , other ): return Expr ('+' , self , other )
218
212
213
+ def __radd__ (self , other ): return Expr ('+' , other , self )
214
+
219
215
def __sub__ (self , other ): return Expr ('-' , self , other )
220
216
221
217
def __and__ (self , other ): return Expr ('&' , self , other )
@@ -253,10 +249,6 @@ def expr(s):
253
249
'x =/= y' parses as (x ^ y) # Logical disequality (xor)
254
250
But BE CAREFUL; precedence of implication is wrong. expr('P & Q ==> R & S')
255
251
is ((P & (Q >> R)) & S); so you must use expr('(P & Q) ==> (R & S)').
256
- >>> expr('P <=> Q(1)')
257
- (P <=> Q(1))
258
- >>> expr('P & Q | ~R(x, F(x))')
259
- ((P & Q) | ~R(x, F(x)))
260
252
"""
261
253
if isinstance (s , Expr ):
262
254
return s
@@ -539,7 +531,7 @@ def distribute_and_over_or(s):
539
531
return FALSE
540
532
if len (s .args ) == 1 :
541
533
return distribute_and_over_or (s .args [0 ])
542
- conj = find_if (( lambda d : d . op == '&' ), s . args )
534
+ conj = first ( arg for arg in s . args if arg . op == '&' )
543
535
if not conj :
544
536
return s
545
537
others = [a for a in s .args if a is not conj ]
@@ -1031,14 +1023,15 @@ def retract(self, sentence):
1031
1023
def fetch_rules_for_goal (self , goal ):
1032
1024
return self .clauses
1033
1025
1034
-
1026
+ """ TODO Rename test_ask to remove test from the name(or tell pytest to ignore it)
1035
1027
def test_ask(query, kb=None):
1036
1028
q = expr(query)
1037
1029
vars = variables(q)
1038
1030
answers = fol_bc_ask(kb or test_kb, q)
1039
1031
return sorted(
1040
1032
[dict((x, v) for x, v in list(a.items()) if x in vars)
1041
1033
for a in answers], key=repr)
1034
+ """
1042
1035
1043
1036
test_kb = FolKB (
1044
1037
list (map (expr , ['Farmer(Mac)' ,
@@ -1229,88 +1222,3 @@ def d(y, x):
1229
1222
# ________________________________________________________________________
1230
1223
1231
1224
1232
- class logicTest :
1233
-
1234
- """
1235
- ### PropKB
1236
- >>> kb = PropKB()
1237
- >>> kb.tell(A & B)
1238
- >>> kb.tell(B >> C)
1239
- >>> kb.ask(C) ## The result {} means true, with no substitutions
1240
- {}
1241
- >>> kb.ask(P)
1242
- False
1243
- >>> kb.retract(B)
1244
- >>> kb.ask(C)
1245
- False
1246
-
1247
- >>> pl_true(P, {})
1248
- >>> pl_true(P | Q, {P: True})
1249
- True
1250
-
1251
- # Notice that the function pl_true cannot reason by cases:
1252
- >>> pl_true(P | ~P)
1253
-
1254
- # However, tt_true can:
1255
- >>> tt_true(P | ~P)
1256
- True
1257
-
1258
- # The following are tautologies from [Fig. 7.11]:
1259
- >>> tt_true("(A & B) <=> (B & A)")
1260
- True
1261
- >>> tt_true("(A | B) <=> (B | A)")
1262
- True
1263
- >>> tt_true("((A & B) & C) <=> (A & (B & C))")
1264
- True
1265
- >>> tt_true("((A | B) | C) <=> (A | (B | C))")
1266
- True
1267
- >>> tt_true("~~A <=> A")
1268
- True
1269
- >>> tt_true("(A >> B) <=> (~B >> ~A)")
1270
- True
1271
- >>> tt_true("(A >> B) <=> (~A | B)")
1272
- True
1273
- >>> tt_true("(A <=> B) <=> ((A >> B) & (B >> A))")
1274
- True
1275
- >>> tt_true("~(A & B) <=> (~A | ~B)")
1276
- True
1277
- >>> tt_true("~(A | B) <=> (~A & ~B)")
1278
- True
1279
- >>> tt_true("(A & (B | C)) <=> ((A & B) | (A & C))")
1280
- True
1281
- >>> tt_true("(A | (B & C)) <=> ((A | B) & (A | C))")
1282
- True
1283
-
1284
- # The following are not tautologies:
1285
- >>> tt_true(A & ~A)
1286
- False
1287
- >>> tt_true(A & B)
1288
- False
1289
-
1290
- ### An earlier version of the code failed on this:
1291
- >>> dpll_satisfiable(A & ~B & C & (A | ~D) & (~E | ~D) & (C | ~D) & (~A | ~F) & (E | ~F) & (~D | ~F) & (B | ~C | D) & (A | ~E | F) & (~A | E | D)) # noqa
1292
- {B: False, C: True, A: True, F: False, D: True, E: False}
1293
-
1294
- ### [Fig. 7.13]
1295
- >>> alpha = expr("~P12")
1296
- >>> to_cnf(Fig[7,13] & ~alpha)
1297
- ((~P12 | B11) & (~P21 | B11) & (P12 | P21 | ~B11) & ~B11 & P12)
1298
- >>> tt_entails(Fig[7,13], alpha)
1299
- True
1300
- >>> pl_resolution(PropKB(Fig[7,13]), alpha)
1301
- True
1302
-
1303
- ### [Fig. 7.15]
1304
- >>> pl_fc_entails(Fig[7,15], expr('SomethingSilly'))
1305
- False
1306
-
1307
- ### Unification:
1308
- >>> unify(x, x, {})
1309
- {}
1310
- >>> unify(x, 3, {})
1311
- {x: 3}
1312
-
1313
-
1314
- >>> to_cnf((P&Q) | (~P & ~Q))
1315
- ((~P | P) & (~Q | P) & (~P | Q) & (~Q | Q))
1316
- """
0 commit comments