"""
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):
""" enuring order of dependency chain: A > B, B > C, ... """
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):
# a register pair meaning/opposite meaning is mandatory
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:
# is information still available?
if (nameA, nameB) in self.relationship[meaning]:
return False
# you cannot define both: A > B and B > A
if (nameB, nameA) in self.relationship[meaning]:
return False
self.relationship[meaning].append((nameA, nameB))
# ensure correct order for later search in dependency chain
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):
# straight forwared query...
if meaning in self.relationship:
meaningBase = self.relationship[meaning]
# is the information directly stored?
if (nameA, nameB) in meaningBase:
return True
else:
if self.indirectQuery(nameA, nameB, meaningBase):
return 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 True
else:
if self.indirectQuery(nameB, nameA, meaningBase):
return True
break
return False
if __name__ == "__main__":
base = KnowledgeBase()
assert base.defineAntagonism("older", "younger")
# trying to store existing information again
assert not base.defineAntagonism("older", "younger")
# trying to store existing information again
assert not base.defineAntagonism("younger", "older")
assert base.defineRelationship("older", "Iris", "Barney")
assert base.defineRelationship("older", "Barney", "Lieschen")
assert base.defineRelationship("older", "Thomas", "Barney")
# trying to store existing information again
assert not base.defineRelationship("older", "Iris" , "Barney")
# trying to generate inconsistent data. Iris cannot be older and
# younger than Barney and Barney cannot be older and younger than Iris
assert not base.defineRelationship("older", "Barney", "Iris")
testData = \
[("older", "Barney", "Lieschen"), # directly stored \
("older", "Thomas", "Lieschen"), # directly stored (indirect query) \
("older", "Thomas", "Barney"), # directly stored \
("older", "Iris", "Lieschen"), # directly stored (indirect query) \
("older", "Iris", "Barney"), # directly stored \
("older", "Thomas", "Iris"), # not defined \
("older", "Iris", "Thomas"), # not defined \
("younger", "Lieschen", "Barney"), # directly stored (inverse search) \
("younger", "Lieschen", "Iris"), # directly stored (inverser, indirect search) \
("younger", "Lieschen", "Thomas"), # directly stored (inverser, indirect search) \
("younger", "Barney", "Iris"), # directly stored (inverse search) \
("younger", "Barney", "Thomas"), # directly stored (inverse search) \
("younger", "Thomas", "Iris"), # not defined \
("younger", "Iris", "Thomas")] # not defined
for meaning, nameA, nameB in testData:
result = base.query(meaning, nameA, nameB)
if result:
print("Is %s %s than %s? -> True!" % (nameA, meaning, nameB))
else:
print("Is %s %s than %s? -> Not enough information!" % (nameA, meaning, nameB))
Diff to Previous Revision
--- revision 1 2011-12-04 18:19:56
+++ revision 2 2012-01-05 08:58:40
@@ -1,28 +1,27 @@
"""
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!
-"""
+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):
+ """ enuring order of dependency chain: A > B, B > C, ... """
if relationA[1] == relationB[0]:
return -1
if relationA[0] < relationB[0]:
@@ -43,6 +42,7 @@
return True
def defineRelationship(self, meaning, nameA, nameB):
+ # a register pair meaning/opposite meaning is mandatory
if not meaning in self.antagonism and \
not meaning in self.antagonism.values():
return False
@@ -50,8 +50,15 @@
if not meaning in self.relationship:
self.relationship[meaning] = [(nameA, nameB)]
else:
+ # is information still available?
+ if (nameA, nameB) in self.relationship[meaning]:
+ return False
+ # you cannot define both: A > B and B > A
+ if (nameB, nameA) in self.relationship[meaning]:
+ return False
+
self.relationship[meaning].append((nameA, nameB))
- # ensure correct order for later search
+ # ensure correct order for later search in dependency chain
self.relationship[meaning].sort(cmp=self.specialCriteria)
return True
@@ -67,17 +74,15 @@
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!"
+ return True
else:
if self.indirectQuery(nameA, nameB, meaningBase):
- return queryText + " - True!"
+ return True
# inverse query...
elif meaning in self.antagonism.values():
@@ -86,34 +91,54 @@
meaningBase = self.relationship[key]
# is the information directly stored?
if (nameB, nameA) in meaningBase:
- return queryText + " - True!"
+ return True
else:
if self.indirectQuery(nameB, nameA, meaningBase):
- return queryText + " - True!"
+ return True
break
- return queryText + " - Not enough information!"
+ return False
if __name__ == "__main__":
base = KnowledgeBase()
- base.defineAntagonism("older", "younger")
- base.defineRelationship("older", "Iris", "Barney")
- base.defineRelationship("older", "Barney", "Lieschen")
- base.defineRelationship("older", "Thomas", "Barney")
+ assert base.defineAntagonism("older", "younger")
- 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"))
+ # trying to store existing information again
+ assert not base.defineAntagonism("older", "younger")
+ # trying to store existing information again
+ assert not base.defineAntagonism("younger", "older")
+
+ assert base.defineRelationship("older", "Iris", "Barney")
+ assert base.defineRelationship("older", "Barney", "Lieschen")
+ assert base.defineRelationship("older", "Thomas", "Barney")
+
+ # trying to store existing information again
+ assert not base.defineRelationship("older", "Iris" , "Barney")
+ # trying to generate inconsistent data. Iris cannot be older and
+ # younger than Barney and Barney cannot be older and younger than Iris
+ assert not base.defineRelationship("older", "Barney", "Iris")
+
+ testData = \
+ [("older", "Barney", "Lieschen"), # directly stored \
+ ("older", "Thomas", "Lieschen"), # directly stored (indirect query) \
+ ("older", "Thomas", "Barney"), # directly stored \
+ ("older", "Iris", "Lieschen"), # directly stored (indirect query) \
+ ("older", "Iris", "Barney"), # directly stored \
+ ("older", "Thomas", "Iris"), # not defined \
+ ("older", "Iris", "Thomas"), # not defined \
+ ("younger", "Lieschen", "Barney"), # directly stored (inverse search) \
+ ("younger", "Lieschen", "Iris"), # directly stored (inverser, indirect search) \
+ ("younger", "Lieschen", "Thomas"), # directly stored (inverser, indirect search) \
+ ("younger", "Barney", "Iris"), # directly stored (inverse search) \
+ ("younger", "Barney", "Thomas"), # directly stored (inverse search) \
+ ("younger", "Thomas", "Iris"), # not defined \
+ ("younger", "Iris", "Thomas")] # not defined
+
+ for meaning, nameA, nameB in testData:
+ result = base.query(meaning, nameA, nameB)
+
+ if result:
+ print("Is %s %s than %s? -> True!" % (nameA, meaning, nameB))
+ else:
+ print("Is %s %s than %s? -> Not enough information!" % (nameA, meaning, nameB))