CS50的Python人工智能入门 – 知识

我正在学习哈佛大学的Python人工智能入门课程,非常享受这个过程。然而,我下载了逻辑文件来使用布尔代数和知识,其中包含简单的操作(如OR、AND、NOT等)。在我提出疑问之前,我将分享来自哈佛源代码的知识类,希望其中没有问题:

这个类的链接:

哈佛课程

logic.py

import itertoolsclass Sentence():    def evaluate(self, model):        """Evaluates the logical sentence."""        raise Exception("nothing to evaluate")    def formula(self):        """Returns string formula representing logical sentence."""        return ""    def symbols(self):        """Returns a set of all symbols in the logical sentence."""        return set()    @classmethod    def validate(cls, sentence):        if not isinstance(sentence, Sentence):            raise TypeError("must be a logical sentence")    @classmethod    def parenthesize(cls, s):        """Parenthesizes an expression if not already parenthesized."""        def balanced(s):            """Checks if a string has balanced parentheses."""            count = 0            for c in s:                if c == "(":                    count += 1                elif c == ")":                    if count <= 0:                        return False                    count -= 1            return count == 0        if not len(s) or s.isalpha() or (            s[0] == "(" and s[-1] == ")" and balanced(s[1:-1])        ):            return s        else:            return f"({s})"class Symbol(Sentence):    def __init__(self, name):        self.name = name    def __eq__(self, other):        return isinstance(other, Symbol) and self.name == other.name    def __hash__(self):        return hash(("symbol", self.name))    def __repr__(self):        return self.name    def evaluate(self, model):        try:            return bool(model[self.name])        except KeyError:            raise Exception(f"variable {self.name} not in model")    def formula(self):        return self.name    def symbols(self):        return {self.name}class Not(Sentence):    def __init__(self, operand):        Sentence.validate(operand)        self.operand = operand    def __eq__(self, other):        return isinstance(other, Not) and self.operand == other.operand    def __hash__(self):        return hash(("not", hash(self.operand)))    def __repr__(self):        return f"Not({self.operand})"    def evaluate(self, model):        return not self.operand.evaluate(model)    def formula(self):        return "¬" + Sentence.parenthesize(self.operand.formula())    def symbols(self):        return self.operand.symbols()class And(Sentence):    def __init__(self, *conjuncts):        for conjunct in conjuncts:            Sentence.validate(conjunct)        self.conjuncts = list(conjuncts)    def __eq__(self, other):        return isinstance(other, And) and self.conjuncts == other.conjuncts    def __hash__(self):        return hash(            ("and", tuple(hash(conjunct) for conjunct in self.conjuncts))        )    def __repr__(self):        conjunctions = ", ".join(            [str(conjunct) for conjunct in self.conjuncts]        )        return f"And({conjunctions})"    def add(self, conjunct):        Sentence.validate(conjunct)        self.conjuncts.append(conjunct)    def evaluate(self, model):        return all(conjunct.evaluate(model) for conjunct in self.conjuncts)    def formula(self):        if len(self.conjuncts) == 1:            return self.conjuncts[0].formula()        return " ∧ ".join([Sentence.parenthesize(conjunct.formula())                           for conjunct in self.conjuncts])    def symbols(self):        return set.union(*[conjunct.symbols() for conjunct in self.conjuncts])class Or(Sentence):    def __init__(self, *disjuncts):        for disjunct in disjuncts:            Sentence.validate(disjunct)        self.disjuncts = list(disjuncts)    def __eq__(self, other):        return isinstance(other, Or) and self.disjuncts == other.disjuncts    def __hash__(self):        return hash(            ("or", tuple(hash(disjunct) for disjunct in self.disjuncts))        )    def __repr__(self):        disjuncts = ", ".join([str(disjunct) for disjunct in self.disjuncts])        return f"Or({disjuncts})"    def evaluate(self, model):        return any(disjunct.evaluate(model) for disjunct in self.disjuncts)    def formula(self):        if len(self.disjuncts) == 1:            return self.disjuncts[0].formula()        return " ∨  ".join([Sentence.parenthesize(disjunct.formula())                            for disjunct in self.disjuncts])    def symbols(self):        return set.union(*[disjunct.symbols() for disjunct in self.disjuncts])class Implication(Sentence):    def __init__(self, antecedent, consequent):        Sentence.validate(antecedent)        Sentence.validate(consequent)        self.antecedent = antecedent        self.consequent = consequent    def __eq__(self, other):        return (isinstance(other, Implication)                and self.antecedent == other.antecedent                and self.consequent == other.consequent)    def __hash__(self):        return hash(("implies", hash(self.antecedent), hash(self.consequent)))    def __repr__(self):        return f"Implication({self.antecedent}, {self.consequent})"    def evaluate(self, model):        return ((not self.antecedent.evaluate(model))                or self.consequent.evaluate(model))    def formula(self):        antecedent = Sentence.parenthesize(self.antecedent.formula())        consequent = Sentence.parenthesize(self.consequent.formula())        return f"{antecedent} => {consequent}"    def symbols(self):        return set.union(self.antecedent.symbols(), self.consequent.symbols())class Biconditional(Sentence):    def __init__(self, left, right):        Sentence.validate(left)        Sentence.validate(right)        self.left = left        self.right = right    def __eq__(self, other):        return (isinstance(other, Biconditional)                and self.left == other.left                and self.right == other.right)    def __hash__(self):        return hash(("biconditional", hash(self.left), hash(self.right)))    def __repr__(self):        return f"Biconditional({self.left}, {self.right})"    def evaluate(self, model):        return ((self.left.evaluate(model)                 and self.right.evaluate(model))                or (not self.left.evaluate(model)                    and not self.right.evaluate(model)))    def formula(self):        left = Sentence.parenthesize(str(self.left))        right = Sentence.parenthesize(str(self.right))        return f"{left} <=> {right}"    def symbols(self):        return set.union(self.left.symbols(), self.right.symbols())def model_check(knowledge, query):    """Checks if knowledge base entails query."""    def check_all(knowledge, query, symbols, model):        """Checks if knowledge base entails query, given a particular model."""        # If model has an assignment for each symbol        if not symbols:            # If knowledge base is true in model, then query must also be true            if knowledge.evaluate(model):                return query.evaluate(model)            return True        else:            # Choose one of the remaining unused symbols            remaining = symbols.copy()            p = remaining.pop()            # Create a model where the symbol is true            model_true = model.copy()            model_true[p] = True            # Create a model where the symbol is false            model_false = model.copy()            model_false[p] = False            # Ensure entailment holds in both models            return (check_all(knowledge, query, remaining, model_true) and                    check_all(knowledge, query, remaining, model_false))    # Get all symbols in both knowledge and query    symbols = set.union(knowledge.symbols(), query.symbols())    # Check that knowledge entails query    return check_all(knowledge, query, symbols, dict())

我知道代码量很大,但我的疑问很简单,我测试了基本的知识布尔代数操作,如NOT、AND和OR。问题只出现在OR函数上,如果至少有一个为真,它应该总是返回TRUE。但它返回的是false。

from logic import *a = Symbol("a")b = Symbol("b")# OR# Error hereorSentence = Or(a, b)valueOrSentence = model_check(orSentence, a)print(orSentence.formula() + f" ({valueOrSentence})")valueOrSentence = model_check(orSentence,  Not(a))print(orSentence.formula() + f" ({valueOrSentence})")print('---/---/---/')

在检查模型时,它应该返回"true",但实际上返回的是"false"

我更愿意相信哈佛的logic.py文件没有错误,我应该如何修复这个“OR”逻辑?


回答:

对于model的一个特定情况,你的knowledge成立但query不成立,因此它返回False。这并没有错。

model = {'a': False, 'b': True}时,orSentence.evaluate(model)会返回True,但a.evaluate(model)会返回False,使得model_check的整体结果为False

如果你使用andSentence = And(a, b)然后运行model_check(andSentence, a),它会返回True,因为对于model的每个值,andSentence(知识)和a(查询)要么都为True,要么都为False

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注