Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8e039f2

Browse files
committed
Fixed issue 13.
1 parent 19a4418 commit 8e039f2

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

logic.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ def pl_true(exp, model={}):
434434

435435
def to_cnf(s):
436436
"""Convert a propositional logical sentence s to conjunctive normal form.
437-
That is, of the form ((A | ~B | ...) & (B | C | ...) & ...) [p. 215]
437+
That is, to the form ((A | ~B | ...) & (B | C | ...) & ...) [p. 215]
438438
>>> to_cnf("~(B|C)")
439439
(~B & ~C)
440440
>>> to_cnf("B <=> (P1|P2)")
@@ -443,6 +443,8 @@ def to_cnf(s):
443443
((b | a | d) & (c | a | d))
444444
>>> to_cnf("A & (B | (D & E))")
445445
(A & (D | B) & (E | B))
446+
>>> to_cnf("A | (B | (C | (D & E)))")
447+
((D | A | B | C) & (E | A | B | C))
446448
"""
447449
if isinstance(s, str): s = expr(s)
448450
s = eliminate_implications(s) # Steps 1, 2 from p. 215
@@ -454,6 +456,8 @@ def eliminate_implications(s):
454456
that is equivalent to s, but has only &, |, and ~ as logical operators.
455457
>>> eliminate_implications(A >> (~B << C))
456458
((~B | ~C) | ~A)
459+
>>> eliminate_implications(A ^ B)
460+
((A & ~B) | (~A & B))
457461
"""
458462
if not s.args or is_symbol(s.op): return s ## (Atoms are unchanged.)
459463
args = map(eliminate_implications, s.args)
@@ -464,7 +468,11 @@ def eliminate_implications(s):
464468
return (a | ~b)
465469
elif s.op == '<=>':
466470
return (a | ~b) & (b | ~a)
471+
elif s.op == '^':
472+
assert len(args) == 2 ## TODO: relax this restriction
473+
return (a & ~b) | (~a & b)
467474
else:
475+
assert s.op in ('&', '|', '~')
468476
return Expr(s.op, *args)
469477

470478
def move_not_inwards(s):
@@ -522,14 +530,18 @@ def NaryExpr(op, *args):
522530
nested instances of the same op up to the top level.
523531
>>> NaryExpr('&', (A&B),(B|C),(B&C))
524532
(A & B & (B | C) & B & C)
533+
>>> NaryExpr('|', A|(B|(C|(A&B))))
534+
(A | B | C | (A & B))
525535
"""
526536
arglist = []
527-
for arg in args:
528-
if arg.op == op: arglist.extend(arg.args)
529-
else: arglist.append(arg)
530-
if len(args) == 1:
531-
return args[0]
532-
elif len(args) == 0:
537+
def collect(subargs):
538+
for arg in subargs:
539+
if arg.op == op: collect(arg.args)
540+
else: arglist.append(arg)
541+
collect(args)
542+
if len(arglist) == 1:
543+
return arglist[0]
544+
elif len(arglist) == 0:
533545
return _NaryExprTable[op]
534546
else:
535547
return Expr(op, *arglist)

0 commit comments

Comments
 (0)