Welcome, guest | Sign In | My Account | Store | Cart
"""
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))

History