def test_column_references_multiple_atoms(self): """Test column references occurring in multiple atoms in a rule.""" ms = compile.ModuleSchemas() ms['nova'] = compile.Schema({'q': ('id', 'name', 'status'), 'r': ('id', 'age', 'weight')}) # Multiple atoms code = ("p(x) :- nova:q(id=x, 2=y), nova:r(id=x)") actual = compile.parse(code, ms) correct = "p(x) :- nova:q(x, x0, y), nova:r(x, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms') # Multiple atoms sharing column name but different variables code = ("p(x) :- nova:q(id=x), nova:r(id=y)") actual = compile.parse(code, ms) correct = "p(x) :- nova:q(x, x0, x1), nova:r(y, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms shared column name') # Multiple atoms, same table code = ("p(x) :- nova:q(id=x, 2=y), nova:q(id=x)") actual = compile.parse(code, ms) correct = "p(x) :- nova:q(x, x0, y), nova:q(x, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms, same table')
def test_column_references_multiple_atoms(self): """Test column references occurring in multiple atoms in a rule.""" run = agnostic.Runtime() run.create_policy('nova') schema = compile.Schema({'q': ('id', 'name', 'status'), 'r': ('id', 'age', 'weight')}) run.set_schema('nova', schema, complete=True) # Multiple atoms code = ("p(x) :- nova:q(id=x, 2=y), nova:r(id=x)") actual = run.parse(code) correct = "p(x) :- nova:q(x, x0, y), nova:r(x, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms') # Multiple atoms sharing column name but different variables code = ("p(x) :- nova:q(id=x), nova:r(id=y)") actual = run.parse(code) correct = "p(x) :- nova:q(x, x0, x1), nova:r(y, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms shared column name') # Multiple atoms, same table code = ("p(x) :- nova:q(id=x, 2=y), nova:q(id=x)") actual = run.parse(code) correct = "p(x) :- nova:q(x, x0, y), nova:q(x, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms, same table')
def test_column_references_multiple_atoms(self): """Test column references occurring in multiple atoms in a rule.""" run = runtime.Runtime() run.create_policy('nova') schema = compile.Schema({ 'q': ('id', 'name', 'status'), 'r': ('id', 'age', 'weight') }) run.set_schema('nova', schema, complete=True) # Multiple atoms code = ("p(x) :- nova:q(id=x, 2=y), nova:r(id=x)") actual = run.parse(code) correct = "p(x) :- nova:q(x, x0, y), nova:r(x, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms') # Multiple atoms sharing column name but different variables code = ("p(x) :- nova:q(id=x), nova:r(id=y)") actual = run.parse(code) correct = "p(x) :- nova:q(x, x0, x1), nova:r(y, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms shared column name') # Multiple atoms, same table code = ("p(x) :- nova:q(id=x, 2=y), nova:q(id=x)") actual = run.parse(code) correct = "p(x) :- nova:q(x, x0, y), nova:q(x, y0, y1)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple atoms, same table')
def check(code, correct, msg): # We're interacting directly with the runtime's underlying # theory b/c we haven't decided whether consequences should # be a top-level API call. run = self.prep_runtime() run.insert(code, target=NREC_THEORY) actual = run.theory[NREC_THEORY].consequences() e = helper.datalog_same(helper.pol2str(actual), correct, msg) self.assertTrue(e)
def check(query, code, tablenames, correct, msg, find_all=True): # We're interacting directly with the runtime's underlying # theory b/c we haven't yet decided whether Abduce should # be a top-level API call. run = self.prep_runtime() run.insert(code, target=NREC_THEORY) query = helper.str2form(query) actual = run.theory[NREC_THEORY].abduce(query, tablenames=tablenames, find_all=find_all) e = helper.datalog_same(helper.pol2str(actual), correct, msg) self.assertTrue(e)
def check(query, code, tablenames, correct, msg, find_all=True): # We're interacting directly with the runtime's underlying # theory b/c we haven't yet decided whether Abduce should # be a top-level API call. run = self.prep_runtime() run.insert(code, target=NREC_THEORY) query = helper.str2form(query) actual = run.theory[NREC_THEORY].abduce( query, tablenames=tablenames, find_all=find_all) e = helper.datalog_same(helper.pol2str(actual), correct, msg) self.assertTrue(e)
def test_theory_inclusion(self): """Test evaluation routines when one theory includes another.""" # spread out across inclusions th1 = runtime.NonrecursiveRuleTheory() th2 = runtime.NonrecursiveRuleTheory() th3 = runtime.NonrecursiveRuleTheory() th1.includes.append(th2) th2.includes.append(th3) th1.insert(helper.str2form('p(x) :- q(x), r(x), s(2)')) th2.insert(helper.str2form('q(1)')) th1.insert(helper.str2form('r(1)')) th3.insert(helper.str2form('s(2)')) self.check_equal(helper.pol2str(th1.select(helper.str2form('p(x)'))), 'p(1)', 'Data spread across inclusions')
def test_theory_inclusion(self): """Test evaluation routines when one theory includes another.""" # spread out across inclusions th1 = agnostic.NonrecursiveRuleTheory() th2 = agnostic.NonrecursiveRuleTheory() th3 = agnostic.NonrecursiveRuleTheory() th1.includes.append(th2) th2.includes.append(th3) th1.insert(helper.str2form('p(x) :- q(x), r(x), s(2)')) th2.insert(helper.str2form('q(1)')) th1.insert(helper.str2form('r(1)')) th3.insert(helper.str2form('s(2)')) self.check_equal( helper.pol2str(th1.select(helper.str2form('p(x)'))), 'p(1)', 'Data spread across inclusions')
def test_column_references_atom(self): """Test column references occurring in a single atom in a rule.""" run = agnostic.Runtime() run.create_policy('nova') nova_schema = compile.Schema({'q': ('id', 'name', 'status')}) run.set_schema('nova', nova_schema, complete=True) # Multiple column names code = ("p(x) :- nova:q(id=x, status=y)") actual = run.parse(code) correct = "p(x) :- nova:q(x, w, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple column names') # Multiple column numbers code = ("p(x) :- nova:q(0=x, 1=y, 2=z)") actual = run.parse(code) correct = "p(x) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple column numbers') # Mix column names and numbers code = ("p(x) :- nova:q(id=x, 2=y)") actual = run.parse(code) correct = "p(x) :- nova:q(x, w, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Mix names and numbers') # Object constants code = ("p(x) :- nova:q(id=3, 2=2)") actual = run.parse(code) correct = "p(x) :- nova:q(3, w, 2)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Object constants') # Out of order code = ("p(x, y) :- nova:q(status=y, id=x)") actual = run.parse(code) correct = "p(x, y) :- nova:q(x, z, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Out of order') # Out of order with numbers code = ("p(x, y) :- nova:q(1=y, 0=x)") actual = run.parse(code) correct = "p(x, y) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Out of order with numbers') # Positional plus named code = ("p(x, y) :- nova:q(x, status=y)") actual = run.parse(code) correct = "p(x, y) :- nova:q(x, z, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Positional plus named') # Positional plus named 2 code = ("p(x, y, z) :- nova:q(x, y, 2=z)") actual = run.parse(code) correct = "p(x, y, z) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Positional plus named 2') # Pure positional (different since we are providing schema) code = ("p(x, y, z) :- nova:q(x, y, z)") actual = run.parse(code) correct = "p(x, y, z) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Pure positional') # Pure positional (without schema) code = ("p(x) :- nova:q(x, y, z)") run.delete_policy('nova') actual = run.parse(code) correct = "p(x) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Pure positional without schema')
def test_column_references_atom(self): """Test column references occurring in a single atom in a rule.""" ms = compile.ModuleSchemas() ms['nova'] = compile.Schema({'q': ('id', 'name', 'status')}) # Multiple column names code = ("p(x) :- nova:q(id=x, status=y)") actual = compile.parse(code, ms) correct = "p(x) :- nova:q(x, w, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple column names') # Multiple column numbers code = ("p(x) :- nova:q(0=x, 1=y, 2=z)") actual = compile.parse(code, ms) correct = "p(x) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple column numbers') # Mix column names and numbers code = ("p(x) :- nova:q(id=x, 2=y)") actual = compile.parse(code, ms) correct = "p(x) :- nova:q(x, w, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Mix names and numbers') # Object constants code = ("p(x) :- nova:q(id=3, 2=2)") actual = compile.parse(code, ms) correct = "p(x) :- nova:q(3, w, 2)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Object constants') # Out of order code = ("p(x, y) :- nova:q(status=y, id=x)") actual = compile.parse(code, ms) correct = "p(x, y) :- nova:q(x, z, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Out of order') # Out of order with numbers code = ("p(x, y) :- nova:q(1=y, 0=x)") actual = compile.parse(code, ms) correct = "p(x, y) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Out of order with numbers') # Positional plus named code = ("p(x, y) :- nova:q(x, status=y)") actual = compile.parse(code, ms) correct = "p(x, y) :- nova:q(x, z, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Positional plus named') # Positional plus named 2 code = ("p(x, y, z) :- nova:q(x, y, 2=z)") actual = compile.parse(code, ms) correct = "p(x, y, z) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Positional plus named 2') # Pure positional (different since we are providing schema) code = ("p(x, y, z) :- nova:q(x, y, z)") actual = compile.parse(code, ms) correct = "p(x, y, z) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Pure positional') # Pure positional (without schema) code = ("p(x) :- nova:q(x, y, z)") actual = compile.parse(code, compile.ModuleSchemas()) correct = "p(x) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Pure positional without schema')
def test_column_references_atom(self): """Test column references occurring in a single atom in a rule.""" run = runtime.Runtime() run.create_policy('nova') nova_schema = compile.Schema({'q': ('id', 'name', 'status')}) run.set_schema('nova', nova_schema, complete=True) # Multiple column names code = ("p(x) :- nova:q(id=x, status=y)") actual = run.parse(code) correct = "p(x) :- nova:q(x, w, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple column names') # Multiple column numbers code = ("p(x) :- nova:q(0=x, 1=y, 2=z)") actual = run.parse(code) correct = "p(x) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Multiple column numbers') # Mix column names and numbers code = ("p(x) :- nova:q(id=x, 2=y)") actual = run.parse(code) correct = "p(x) :- nova:q(x, w, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Mix names and numbers') # Object constants code = ("p(x) :- nova:q(id=3, 2=2)") actual = run.parse(code) correct = "p(x) :- nova:q(3, w, 2)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Object constants') # Out of order code = ("p(x, y) :- nova:q(status=y, id=x)") actual = run.parse(code) correct = "p(x, y) :- nova:q(x, z, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Out of order') # Out of order with numbers code = ("p(x, y) :- nova:q(1=y, 0=x)") actual = run.parse(code) correct = "p(x, y) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Out of order with numbers') # Positional plus named code = ("p(x, y) :- nova:q(x, status=y)") actual = run.parse(code) correct = "p(x, y) :- nova:q(x, z, y)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Positional plus named') # Positional plus named 2 code = ("p(x, y, z) :- nova:q(x, y, 2=z)") actual = run.parse(code) correct = "p(x, y, z) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Positional plus named 2') # Pure positional (different since we are providing schema) code = ("p(x, y, z) :- nova:q(x, y, z)") actual = run.parse(code) correct = "p(x, y, z) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Pure positional') # Pure positional (without schema) code = ("p(x) :- nova:q(x, y, z)") run.delete_policy('nova') actual = run.parse(code) correct = "p(x) :- nova:q(x, y, z)" eq = helper.datalog_same(helper.pol2str(actual), correct) self.assertTrue(eq, 'Pure positional without schema')