""" Result of this application: Is Barney older than Lieschen? - True! Is Thomas older than Lieschen? - True! Is Thomas older than Barney? - True! Is Iris older than Lieschen? - True! Is Iris older than Barney? - True! Is Thomas older than Iris? - Not enough information! Is Iris older than Thomas? - Not enough information! Is Lieschen younger than Barney? - True! Is Lieschen younger than Iris? - True! Is Lieschen younger than Thomas? - True! Is Barney younger than Iris? - True! Is Barney younger than Thomas? - True! Is Thomas younger than Iris? - Not enough information! Is Iris younger than Thomas? - Not enough information! """ class KnowledgeBase: def __init__(self): self.antagonism = {} self.relationship = {} def specialCriteria(self, relationA, relationB): if relationA[1] == relationB[0]: return -1 if relationA[0] < relationB[0]: return -1 if relationA[0] == relationB[0]: if relationA[1] < relationB[1]: return -1 elif relationA[1] > relationB[1]: return 1 return 0 def defineAntagonism(self, meaning, oppositeMeaning): if meaning in self.antagonism or \ oppositeMeaning in self.antagonism: return False self.antagonism[meaning] = oppositeMeaning return True def defineRelationship(self, meaning, nameA, nameB): if not meaning in self.antagonism and \ not meaning in self.antagonism.values(): return False if not meaning in self.relationship: self.relationship[meaning] = [(nameA, nameB)] else: self.relationship[meaning].append((nameA, nameB)) # ensure correct order for later search self.relationship[meaning].sort(cmp=self.specialCriteria) return True def indirectQuery(self, nameA, nameB, meaningBase): search = nameA for key , value in meaningBase: if key == search: search = value if search == nameB: break return search == nameB def query(self, meaning, nameA, nameB): queryText = "Is %s %s than %s?" % (nameA, meaning, nameB) # straight forwared query... if meaning in self.relationship: meaningBase = self.relationship[meaning] # is the information directly stored? if (nameA, nameB) in meaningBase: return queryText + " - True!" else: if self.indirectQuery(nameA, nameB, meaningBase): return queryText + " - True!" # inverse query... elif meaning in self.antagonism.values(): for key, value in self.antagonism.items(): if value == meaning: meaningBase = self.relationship[key] # is the information directly stored? if (nameB, nameA) in meaningBase: return queryText + " - True!" else: if self.indirectQuery(nameB, nameA, meaningBase): return queryText + " - True!" break return queryText + " - Not enough information!" if __name__ == "__main__": base = KnowledgeBase() base.defineAntagonism("older", "younger") base.defineRelationship("older", "Iris", "Barney") base.defineRelationship("older", "Barney", "Lieschen") base.defineRelationship("older", "Thomas", "Barney") print(base.query("older", "Barney", "Lieschen")) print(base.query("older", "Thomas", "Lieschen")) print(base.query("older", "Thomas", "Barney")) print(base.query("older", "Iris", "Lieschen")) print(base.query("older", "Iris", "Barney")) print(base.query("older", "Thomas", "Iris")) print(base.query("older", "Iris", "Thomas")) print("") print(base.query("younger", "Lieschen", "Barney")) print(base.query("younger", "Lieschen", "Iris")) print(base.query("younger", "Lieschen", "Thomas")) print(base.query("younger", "Barney", "Iris")) print(base.query("younger", "Barney", "Thomas")) print(base.query("younger", "Thomas", "Iris")) print(base.query("younger", "Iris", "Thomas"))