Fix bug with policy negation and multiple policies

If negation is applied to an atom that references a different
policy, that negation always succeeds.  The root cause was
that negation caused the evaluation engine to skip over
the logic that runs the evaluation routine within another
policy.  This meant that the evaluation engine could
never prove anything positive in that other policy and
hence the negation always succeeded.

This change routes the logic through the normal evaluation
path.  This ensures that what is inside the negation is
evaluated exactly the same as if it were outside the
negation.

Change-Id: I2d5ceeccf87afd99adfe71c359cf2b5e5cd46b38
Closes-bug: 1448295
This commit is contained in:
Tim Hinrichs 2015-04-24 13:27:20 -07:00
parent a888cf26d5
commit ced8a68db1
2 changed files with 11 additions and 1 deletions

View File

@ -296,7 +296,7 @@ class TopDownTheory(Theory):
# as we can.
# Ensure save=None so that abduction does not save anything.
# Saving while performing NAF makes no sense.
if self._top_down_includes(new_context, new_caller):
if self._top_down_eval(new_context, new_caller):
self._print_fail(lit, context.binding, context.depth)
return False
else:

View File

@ -855,6 +855,16 @@ class TestMultipolicyRules(base.TestCase):
self.assertTrue(g.edge_in('test:p', 'test:s', False))
self.assertTrue(g.edge_in('test:q', 'nova:r', False))
def test_negation(self):
"""Test that negation when applied to a different policy works."""
run = agnostic.Runtime()
run.debug_mode()
run.create_policy('alpha')
run.create_policy('beta')
run.insert('p(x) :- beta:q(x), not beta:q(x)', 'alpha')
run.insert('q(1)', 'beta')
self.assertEqual(run.select('p(x)', 'alpha'), '')
class TestSelect(base.TestCase):
def test_no_dups(self):