陳鍾誠

Version 1.0

實作:布林邏輯的推論引擎

程式碼:推理引擎

import re

class KB:
    def __init__(self):
        self.rules = []
        self.facts = {}
        self.dict = {}

    def load(self, code):
        lines = re.split(r'[\.]+ ?', code)
        # lines = code.split(/[\.]+ ?/);
        print(lines)
        for line in lines:
            if len(line.strip()) > 0:
                self.addRule(line)

    def isFact(self, term):
        if len(term) == 0:
            return True
        return self.facts.get(term) != None

    def check(self, rule):
        for term in rule['terms']:
            if self.isFact(term.strip()):
                continue
            else:
                return False
        return True

    def addFact(self, term):
        self.facts[term] = True
        print("addFact({})".format(term))

    def addRule(self, line):
        m = re.match(r"^([^<=]*)(<=(.*))?$", line)
        head = "" if m.group(1)==None else m.group(1).strip()
        # print('addRule: m.group(3)=', m.group(3))
        terms= "" if m.group(3)==None else m.group(3).strip().split(r"&")
        print("rule:head={} terms={}".format(head, terms))
        rule = {
          'head': head,
          'terms':terms,
          'satisfy':False
        }
        self.rules.append(rule)
        self.dict[head] = {
          'headHits': [rule],
          'bodyHits': []
        }

    def forwardChaining(self):
        while True:
            anySatisfy = False

            for rule in self.rules:
                if not rule['satisfy']:
                    if self.check(rule):
                        self.addFact(rule['head'])
                        rule['satisfy'] = True
                        anySatisfy = True
                
            if not anySatisfy:
                break

        print("facts=", self.facts.keys())

簡易的測試程式

https://github.com/ccccourse/ai/blob/master/python/06-logic/kbTest.py

from kb import KB

code = "A<=B. B<=C&D. C<=E. D<=F. E. F. Z<=C&D&G."
kb1 = KB()
kb1.load(code)
kb1.forwardChaining()

執行結果

mac020:06-logic mac020$ python3 kbTest.py
['A<=B', 'B<=C&D', 'C<=E', 'D<=F', 'E', 'F', 'Z<=C&D&G', '']
rule:head=A terms=['B']
rule:head=B terms=['C', 'D']
rule:head=C terms=['E']
rule:head=D terms=['F']
rule:head=E terms=
rule:head=F terms=
rule:head=Z terms=['C', 'D', 'G']
addFact(E)
addFact(F)
addFact(C)
addFact(D)
addFact(B)
addFact(A)
facts= dict_keys(['E', 'F', 'C', 'D', 'B', 'A'])

結語

以上我們實作了一個簡易的布林邏輯推論引擎,採用洪氏邏輯的語法,以及前向推論 (forwardChaining) 的方式。