From dfdbda44064e65914496d10f51f18aecd3c721ba Mon Sep 17 00:00:00 2001 From: Emi Simpson Date: Mon, 6 Mar 2023 14:16:03 -0500 Subject: [PATCH] Fixed a bug which caused unnecessary infinite recursion --- resolution.py | 58 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/resolution.py b/resolution.py index b9af348..48ffc2f 100644 --- a/resolution.py +++ b/resolution.py @@ -134,8 +134,8 @@ i.e. the empty clause def next_generation( - previous_generations: KnowledgeBase_, - current_generation: KnowledgeBase_, + previous_generations: KnowledgeBase, + current_generation: KnowledgeBase, ) -> KnowledgeBase: """ Advance resolution by one step @@ -154,13 +154,13 @@ def next_generation( empty list for previous generations indicates that this is the zeroth (original) knowledge base. - >>> next_generation([ - ... ], [ - ... [IRNeg(IRProp('animal', [IRProp('Kim')]))], - ... [IRNeg(IRProp('dog', [IRVar('x0')])), IRProp('animal', [IRVar('x0')])], - ... [IRNeg(IRProp('cat', [IRVar('x1')])), IRProp('animal', [IRVar('x1')])], - ... [IRProp('dog', [IRProp('Kim')])], - ... ]) #doctest: +NORMALIZE_WHITESPACE + >>> next_generation(fset( + ... ), fset( + ... fset( IRNeg(IRProp('animal', (IRProp('Kim'),))) ), + ... fset( IRNeg(IRProp('dog', (IRVar('x0'),))), IRProp('animal', (IRVar('x0'),)) ), + ... fset( IRNeg(IRProp('cat', (IRVar('x1'),))), IRProp('animal', (IRVar('x1'),)) ), + ... fset( IRProp('dog', (IRProp('Kim'),)) ), + ... )) #doctest: +NORMALIZE_WHITESPACE { { animal(Kim()) }, { ¬cat(Kim()) }, @@ -171,24 +171,40 @@ def next_generation( the first generation have been moved to the previous generations knowledge base, and the current generation contains only the results from the first call. - >>> next_generation([ - ... [IRNeg(IRProp('animal', [IRProp('Kim')]))], - ... [IRNeg(IRProp('dog', [IRVar('x0')])), IRProp('animal', [IRVar('x0')])], - ... [IRNeg(IRProp('cat', [IRVar('x1')])), IRProp('animal', [IRVar('x1')])], - ... [IRProp('dog', [IRProp('Kim')])], - ... ], [ - ... [IRNeg(IRProp('dog', [IRProp('Kim')]))], - ... [IRNeg(IRProp('cat', [IRProp('Kim')]))], - ... [IRProp('animal', [IRProp('Kim')])], - ... ]) + >>> next_generation(fset( + ... fset( IRNeg(IRProp('animal', (IRProp('Kim'),))) ), + ... fset( IRNeg(IRProp('dog', (IRVar('x0'),))), IRProp('animal', (IRVar('x0'),)) ), + ... fset( IRNeg(IRProp('cat', (IRVar('x1'),))), IRProp('animal', (IRVar('x1'),)) ), + ... fset( IRProp('dog', (IRProp('Kim'),)) ), + ... ), fset( + ... fset( IRNeg(IRProp('dog', (IRProp('Kim'),))) ), + ... fset( IRNeg(IRProp('cat', (IRProp('Kim'),))) ), + ... fset( IRProp('animal', (IRProp('Kim'),)) ), + ... )) { { } } The return of a knowledge base containing false (ie `[]`) indicates that resolution has found a contradiction. In this case, there are two: One from ¬dog(Kim) and dog(Kim), and one from animal(Kim) and ¬animal(Kim). - """ - return fset(*derive(current_generation), *derive2(current_generation, previous_generations)) + Excluded from the next generation is any term which exists in a previous generation. + For example: + + >>> next_generation(fset( + ... ), fset( + ... fset( IRNeg(IRProp('day')), IRProp('day') ), + ... fset( IRProp('day') ), + ... )) + { } + + This configuration could theoretically derive day() again, however, it does not, + because that is already known, and is present in the current generation. + """ + return FSet( + (derive(current_generation) | derive2(current_generation, previous_generations)) + - current_generation + - previous_generations + ) def derives_false( knowledge_base: KnowledgeBase, previous_generations: KnowledgeBase = FSet(),