Lab-7 Solution
Lab-7 Solution
Description:
Students will create a knowledge base first-order logic to represent facts about a family tree,
such as parent, sibling and grandparent relationship, and write a function to answer queries
about these relationships.
data.py
def load_data(pyDatalog):
#Generation 1
gen1 = ["Jose Arcadio Buendia", "Ursula Iguaran"]
pyDatalog.assert_fact('married', gen1[0], gen1[1])
pyDatalog.assert_fact('cousin', gen1[0], gen1[1])
pyDatalog.assert_fact('buendia_blood', gen1[0], True)
pyDatalog.assert_fact('buendia_blood', gen1[1], True)
pyDatalog.assert_fact('gender', gen1[0], 'Male')
pyDatalog.assert_fact('gender', gen1[1], 'Female')
# Generation 2
gen2 = ["Colonel Aureliano Buendia", "Jose Arcadio Buendia (II)", "Amaranta Buendia",
"Pilar Ternera", "Remedios Moscote", "Rebeca Buendia"]
pyDatalog.assert_fact('parent', gen1[0], gen2[0])
pyDatalog.assert_fact('parent', gen1[1], gen2[0])
pyDatalog.assert_fact('parent', gen1[0], gen2[1])
pyDatalog.assert_fact('parent', gen1[1], gen2[1])
pyDatalog.assert_fact('parent', gen1[0], gen2[2])
pyDatalog.assert_fact('parent', gen1[1], gen2[2])
pyDatalog.assert_fact('gender', gen2[2], 'Female')
pyDatalog.assert_fact('gender', gen2[0], 'Male')
pyDatalog.assert_fact('gender', gen2[1], 'Male')
pyDatalog.assert_fact('gender', gen2[3], 'Female')
pyDatalog.assert_fact('gender', gen2[4], 'Female')
pyDatalog.assert_fact('gender', gen2[5], 'Female')
pyDatalog.assert_fact('buendia_blood', gen2[0], True)
pyDatalog.assert_fact('buendia_blood', gen2[1], True)
pyDatalog.assert_fact('buendia_blood', gen2[2], True)
pyDatalog.assert_fact('buendia_blood', gen2[3], False)
pyDatalog.assert_fact('buendia_blood', gen2[4], False)
pyDatalog.assert_fact('buendia_blood', gen2[5], False)
pyDatalog.assert_fact('buendia', gen2[0], True)
pyDatalog.assert_fact('buendia', gen2[1], True)
pyDatalog.assert_fact('buendia', gen2[2], True)
pyDatalog.assert_fact('buendia', gen2[3], False)
pyDatalog.assert_fact('buendia', gen2[4], True)
pyDatalog.assert_fact('buendia', gen2[5], True)
pyDatalog.assert_fact('married', gen2[0], gen2[4])
pyDatalog.assert_fact('married', gen2[1], gen2[5])
# Generation 3
gen3 = ["The 17 Aurelianos", "Aureliano Jose Buendia", "Arcadio (Jose Arcadio III)",
"Santa Sofia de la Piedad"]
pyDatalog.assert_fact('parent', gen2[0], gen3[0])
pyDatalog.assert_fact('parent', gen2[0], gen3[1])
pyDatalog.assert_fact('parent', gen2[3], gen3[1])
pyDatalog.assert_fact('parent', gen2[1], gen3[2])
pyDatalog.assert_fact('parent', gen2[3], gen3[2])
pyDatalog.assert_fact('gender', gen3[0], 'Male')
pyDatalog.assert_fact('gender', gen3[1], 'Male')
pyDatalog.assert_fact('gender', gen3[2], 'Male')
pyDatalog.assert_fact('gender', gen3[3], 'Female')
pyDatalog.assert_fact('buendia_blood', gen3[0], True)
pyDatalog.assert_fact('buendia_blood', gen3[1], True)
pyDatalog.assert_fact('buendia_blood', gen3[2], True)
pyDatalog.assert_fact('buendia_blood', gen3[3], False)
pyDatalog.assert_fact('buendia', gen3[0], True)
pyDatalog.assert_fact('buendia', gen3[1], True)
pyDatalog.assert_fact('buendia', gen3[2], True)
pyDatalog.assert_fact('buendia', gen3[3], True)
pyDatalog.assert_fact('married', gen3[2], gen3[3])
# Generation 4
gen4 = ["Remedios the Beauty", "Fernanda del Carpio", "Aureliano Segundo Buendia",
"Jose Arcadio Segundo Buendia"]
pyDatalog.assert_fact('parent', gen3[2], gen4[0])
pyDatalog.assert_fact('parent', gen3[3], gen4[0])
pyDatalog.assert_fact('parent', gen3[2], gen4[2])
pyDatalog.assert_fact('parent', gen3[3], gen4[2])
pyDatalog.assert_fact('parent', gen3[2], gen4[3])
pyDatalog.assert_fact('parent', gen3[3], gen4[3])
pyDatalog.assert_fact('gender', gen4[0], 'Female')
pyDatalog.assert_fact('gender', gen4[1], 'Female')
pyDatalog.assert_fact('gender', gen4[2], 'Male')
pyDatalog.assert_fact('gender', gen4[3], 'Male')
pyDatalog.assert_fact('buendia_blood', gen4[0], True)
pyDatalog.assert_fact('buendia_blood', gen4[1], False)
pyDatalog.assert_fact('buendia_blood', gen4[2], True)
pyDatalog.assert_fact('buendia_blood', gen4[3], True)
pyDatalog.assert_fact('buendia', gen4[0], True)
pyDatalog.assert_fact('buendia', gen4[1], True)
pyDatalog.assert_fact('buendia', gen4[2], True)
pyDatalog.assert_fact('buendia', gen4[3], True)
pyDatalog.assert_fact('married', gen4[2], gen4[1])
gen5 = ['Jose Arcadio Buendia (IV)', 'Renata Remedios Buendia (Meme)', 'Mauricio
Babilonia', 'Amaranta Ursula Buendia']
pyDatalog.assert_fact('parent', gen4[2], gen5[0])
pyDatalog.assert_fact('parent', gen4[1], gen5[0])
pyDatalog.assert_fact('parent', gen4[2], gen5[1])
pyDatalog.assert_fact('parent', gen4[1], gen5[1])
pyDatalog.assert_fact('parent', gen4[2], gen5[3])
pyDatalog.assert_fact('parent', gen4[1], gen5[3])
pyDatalog.assert_fact('gender', gen5[0], 'Male')
pyDatalog.assert_fact('gender', gen5[1], 'Female')
pyDatalog.assert_fact('gender', gen5[2], 'Male')
pyDatalog.assert_fact('gender', gen5[3], 'Female')
pyDatalog.assert_fact('buendia_blood', gen5[0], True)
pyDatalog.assert_fact('buendia_blood', gen5[1], True)
pyDatalog.assert_fact('buendia_blood', gen5[2], False)
pyDatalog.assert_fact('buendia_blood', gen5[3], True)
pyDatalog.assert_fact('buendia', gen5[0], True)
pyDatalog.assert_fact('buendia', gen5[1], True)
pyDatalog.assert_fact('buendia', gen5[2], False)
pyDatalog.assert_fact('buendia', gen5[3], True)
gen6 = ['Aureliano (II)', 'Gaston']
pyDatalog.assert_fact('parent', gen5[1], gen6[0])
pyDatalog.assert_fact('parent', gen5[2], gen6[0])
pyDatalog.assert_fact('gender', gen6[0], 'Male')
pyDatalog.assert_fact('gender', gen6[1], 'Male')
pyDatalog.assert_fact('buendia_blood', gen6[0], True)
pyDatalog.assert_fact('buendia_blood', gen6[1], False)
pyDatalog.assert_fact('buendia', gen6[0], True)
pyDatalog.assert_fact('buendia', gen6[1], False)
pyDatalog.assert_fact('married', gen6[1], gen5[3])
gen7 = ['Aureliano (III)']
pyDatalog.assert_fact('parent', gen6[0], gen7[0])
pyDatalog.assert_fact('parent', gen5[3], gen7[0])
pyDatalog.assert_fact('buendia_blood', gen7[0], True)
pyDatalog.assert_fact('buendia', gen7[0], True)
def initialize():
variables = 'V, W, X, Y, Z'
functions = 'gender, buendia_blood, buendia, bastard, inbred, parent, mother, father,
sibling, brother, sister, child, daughter, son, married, wife, husband, decendent, ancestor, aunt,
uncle, cousin'
pyDatalog.create_terms(variables + ', ' + functions)
def load_data():
data.load_data(pyDatalog)
def load_logic():
logic.load_logic(pyDatalog)
def main():
initialize()
load_data()
load_logic()
if __name__ == "__main__":
main()
pass
test.py
import unittest
import buendia_tree
from pyDatalog import pyDatalog
class TestParentRelations(unittest.TestCase):
def setUp(self):
buendia_tree.main()
def test_parent_child(self):
query = 'parent(X, "Amaranta Buendia")'
answers = sorted(pyDatalog.ask(query).answers)
expected_answers = sorted([('Ursula Iguaran',), ('Jose Arcadio Buendia',)])
self.assertEqual(answers,expected_answers)
def test_father_child(self):
query = 'father(X, "Amaranta Buendia")'
answers = pyDatalog.ask(query).answers
expected_answers = [('Jose Arcadio Buendia',)]
self.assertEqual(answers,expected_answers)
def test_mother_child(self):
query = 'mother(X, "Amaranta Buendia")'
answers = pyDatalog.ask(query).answers
expected_answers = [('Ursula Iguaran',)]
self.assertEqual(answers,expected_answers)
def test_bastard(self):
query = 'bastard(X)'
answers = pyDatalog.ask(query).answers
expected_answers = ('Aureliano (III)',)
self.assertIn(expected_answers, answers)
class TestFamily(unittest.TestCase):
def setUp(self):
buendia_tree.main()
def test_siblings(self):
query = 'sibling(X, "Colonel Aureliano Buendia")'
answers = sorted(pyDatalog.ask(query).answers)
expected_answers = sorted([("Jose Arcadio Buendia (II)", ), ("Amaranta Buendia", )])
self.assertEqual(expected_answers, answers)
def test_brother(self):
query = 'brother(X, "Colonel Aureliano Buendia")'
answers = pyDatalog.ask(query).answers
expected_answers = [("Jose Arcadio Buendia (II)", )]
self.assertEqual(expected_answers, answers)
def test_sister(self):
query = 'sister(X, "Colonel Aureliano Buendia")'
answers = pyDatalog.ask(query).answers
expected_answers = [("Amaranta Buendia", )]
self.assertEqual(expected_answers, answers)
def test_cousin(self):
query = 'cousin(X, "Aureliano Jose Buendia")'
answers = pyDatalog.ask(query).answers
expected_answers = [("Arcadio (Jose Arcadio III)", )]
self.assertEqual(expected_answers, answers)
def test_aunt(self):
query = 'aunt(X, "Aureliano (II)")'
answers = pyDatalog.ask(query).answers
expected_answers = [("Amaranta Ursula Buendia", )]
self.assertEqual(expected_answers, answers)
def test_uncle(self):
query = 'uncle(X, "Aureliano (II)")'
answers = sorted(pyDatalog.ask(query).answers)
expected_answers = sorted([("Gaston", ), ("Jose Arcadio Buendia (IV)", )])
self.assertEqual(expected_answers, answers)
def test_ancestor(self):
query = 'ancestor(X, "Aureliano (II)")'
answers = sorted(pyDatalog.ask(query).answers)
expected_answers = ("Fernanda del Carpio", )
self.assertIn(expected_answers, answers)
def test_decendent(self):
query = 'decendent(X, "Fernanda del Carpio")'
answers = sorted(pyDatalog.ask(query).answers)
expected_answers = ("Aureliano (II)", )
self.assertIn(expected_answers, answers)
def main():
buendia_tree.main()
query = "parent(X, Y)"
answers = pyDatalog.ask(query).answers
for ans in answers:
print(ans)
pass
if __name__ == "__main__":
main()
Output
('Amaranta Ursula Buendia', 'Aureliano (III)')
('Aureliano (II)', 'Aureliano (III)')
('Mauricio Babilonia', 'Aureliano (II)')
('Renata Remedios Buendia (Meme)', 'Aureliano (II)')
('Fernanda del Carpio', 'Amaranta Ursula Buendia')
('Aureliano Segundo Buendia', 'Amaranta Ursula Buendia')
('Fernanda del Carpio', 'Renata Remedios Buendia (Meme)')
('Aureliano Segundo Buendia', 'Renata Remedios Buendia (Meme)')
('Fernanda del Carpio', 'Jose Arcadio Buendia (IV)')
('Aureliano Segundo Buendia', 'Jose Arcadio Buendia (IV)')
('Santa Sofia de la Piedad', 'Jose Arcadio Segundo Buendia')
('Arcadio (Jose Arcadio III)', 'Jose Arcadio Segundo Buendia')
('Santa Sofia de la Piedad', 'Aureliano Segundo Buendia')
('Arcadio (Jose Arcadio III)', 'Aureliano Segundo Buendia')
('Santa Sofia de la Piedad', 'Remedios the Beauty')
('Arcadio (Jose Arcadio III)', 'Remedios the Beauty')
('Pilar Ternera', 'Arcadio (Jose Arcadio III)')
('Jose Arcadio Buendia (II)', 'Arcadio (Jose Arcadio III)')
('Pilar Ternera', 'Aureliano Jose Buendia')
('Colonel Aureliano Buendia', 'Aureliano Jose Buendia')
('Colonel Aureliano Buendia', 'The 17 Aurelianos')
('Ursula Iguaran', 'Amaranta Buendia')
('Jose Arcadio Buendia', 'Amaranta Buendia')
('Ursula Iguaran', 'Jose Arcadio Buendia (II)')
('Jose Arcadio Buendia', 'Jose Arcadio Buendia (II)')
('Ursula Iguaran', 'Colonel Aureliano Buendia')
('Jose Arcadio Buendia', 'Colonel Aureliano Buendia')