逻辑智能体

逻辑建模

在讲解逻辑智能体之前,首先让我们用Python实现对基本逻辑符号、语句的建模。
1.Expr类:将输入(“x",“2”)等转换为智能体可以理解的命题符号,其中expr函数实现了将(“==>”)转换为(“>>”)的功能,以求将逻辑连接词标准化。

class Expr:
    """A symbolic mathematical expression.  We use this class for logical
    expressions, and for terms within logical expressions. In general, an
    Expr has an op (operator) and a list of args.  The op can be:
      Null-ary (no args) op:
        A number, representing the number itself.  (e.g. Expr(42) => 42)
        A symbol, representing a variable or constant (e.g. Expr('F') => F)
      Unary (1 arg) op:
        '~', '-', representing NOT, negation (e.g. Expr('~', Expr('P')) => ~P)
      Binary (2 arg) op:
        '>>', '<<', representing forward and backward implication
        '+', '-', '*', '/', '**', representing arithmetic operators
        '<', '>', '>=', '<=', representing comparison operators
        '<=>', '^', representing logical equality and XOR
      N-ary (0 or more args) op:
        '&', '|', representing conjunction and disjunction
        A symbol, representing a function term or FOL proposition

    Exprs can be constructed with operator overloading: if x and y are Exprs,
    then so are x + y and x & y, etc.  Also, if F and x are Exprs, then so is
    F(x); it works by overloading the __call__ method of the Expr F.  Note
    that in the Expr that is created by F(x), the op is the str 'F', not the
    Expr F.   See http://www.python.org/doc/current/ref/specialnames.html
    to learn more about operator overloading in Python.

    WARNING: x == y and x != y are NOT Exprs.  The reason is that we want
    to write code that tests 'if x == y:' and if x == y were the same
    as Expr('==', x, y), then the result would always be true; not what a
    programmer would expect.  But we still need to form Exprs representing
    equalities and disequalities.  We concentrate on logical equality (or
    equivalence) and logical disequality (or XOR).  You have 3 choices:
        (1) Expr('<=>', x, y) and Expr('^', x, y)
            Note that ^ is bitwose XOR in Python (and Java and C++)
        (2) expr('x <=> y') and expr('x =/= y').
            See the doc string for the function expr.
        (3) (x % y) and (x ^ y).
            It is very ugly to have (x % y) mean (x <=> y), but we need
            SOME operator to make (2) work, and this seems the best choice.

    WARNING: if x is an Expr, then so is x + 1, because the int 1 gets
    coerced to an Expr by the constructor.  But 1 + x is an error, because
    1 doesn't know how to add an Expr.  (Adding an __radd__ method to Expr
    wouldn't help, because int.__add__ is still called first.) Therefore,
    you should use Expr(1) + x instead, or ONE + x, or expr('1 + x').
    """

    def __init__(self, op, *args):
        "Op is a string or number; args are Exprs (or are coerced to Exprs)."
        assert isinstance(op, str) or (isnumber(op) and not args)
        self.op = num_or_str(op)
        self.args = tuple(map(expr, args)) ## Coerce args to Exprs
        if not args and not is_prop_symbol(self.op):
            raise SyntaxError("Unacceptable symbol base name (%s). Name must start with an upper-case alphabetic character that and is not TRUE or FALSE." % self.op)

    def __call__(self, *args):
        """Self must be a symbol with no args, such as Expr('F').  Create a new
        Expr with 'F' as op and the args as arguments."""
        assert is_symbol(self.op) and not self.args
        return Expr(self.op, *args)

    def __repr__(self):
        "Show something like 'P' or 'P(x, y)', or '~P' or '(P | Q | R)'"
        if not self.args:         # Constant or proposition with arity 0
            return str(self.op)
        elif is_symbol(self.op):  # Functional or propositional operator
            return '%s(%s)' % (self.op, ', '.join(map(repr, self.args)))
        elif len(self.args) == 1: # Prefix operator
            return self.op + repr(self.args[0])
        else:                     # Infix operator
            return '(%s)' % (' '+self.op+' ').join(map(repr, self.args))

    def __eq__(self, other):
        """x and y are equal iff their ops and args are equal."""
        return (other is self) or (isinstance(other, Expr)
            and self.op == other.op and self.args == other.args)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        "Need a hash method so Exprs can live in dicts."
        return hash(self.op) ^ hash(tuple(self.args))

    # See http://www.python.org/doc/current/lib/module-operator.html
    # Not implemented: not, abs, pos, concat, contains, *item, *slice
    def __lt__(self, other):     return Expr('<',  self, other)
    def __le__(self, other):     return Expr('<=', self, other)
    def __ge__(self, other):     return Expr('>=', self, other)
    def __gt__(self, other):     return Expr('>',  self, other)
    def __add__(self, other):    return Expr('+',  self, other)
    def __sub__(self, other):    return Expr('-',  self, other)
    def __and__(self, other):    return Expr('&',  self, other)
    def __div__(self, other):    return Expr('/',  self, other)
    def __truediv__(self, other):return Expr('/',  self, other)
    def __invert__(self):        return Expr('~',  self)
    def __lshift__(self, other): return Expr('<<', self, other)
    def __rshift__(self, other): return Expr('>>', self, other)
    def __mul__(self, other):    return Expr('*',  self, other)
    def __neg__(self):           return Expr('-',  self)
    def __or__(self, other):     return Expr('|',  self, other)
    def __pow__(self, other):    return Expr('**', self, other)
    def __xor__(self, other):    return Expr('^',  self, other)
    def __mod__(self, other):    return Expr('<=>',  self, other)

2.PropSymbolExpr类:将人类表达的语言,例如:(bob, x,y,t)(bob在t时刻位于x,y位置,转换为智能体可以理解的命题符号。

class PropSymbolExpr(Expr):
    """An extension of Expr intended to represent a symbol. This SymbolExpr
    is a convenience for naming symbols, especially symbols whose names
    indicate an indexed value (e.g. Position[x,y] or Fluent[t]).
    Symbol name must begin with a capital letter. This class helps to add
    brackets with enumerated indices to the end of the name.
    """
    def __init__(self, sym_str, *index):
        """Constructor taking a propositional logic symbol name and an optional set of index values,
        creating a symbol with the base name followed by brackets with the specific
        indices.
        sym_str: String representing base name for symbol. Must begin with a capital letter.
        Examples:
        >>> red = PropSymbolExpr("R")
        >>> print(red)
        R
        >>> turnLeft7 = PropSymbolExpr("Left",7)
        >>> print(turnLeft7)
        Left[7]
        >>> pos_2_3 = PropSymbolExpr("P",2,3)
        >>> print(pos_2_3)
        P[2,3]
        """
        if not is_prop_symbol(sym_str):
            raise SyntaxError("Unacceptable symbol base name (%s). Name must start with an upper-case alphabetic character that and is not TRUE or FALSE." % sym_str)
        self.sym_str = sym_str
        self.indicies = index
        
        if len(index) == 0:
            Expr.__init__(self, sym_str)
        elif len(index) == 1:
            Expr.__init__(self, '%s[%d]' % (sym_str, index[0]))
        elif len(index) == 2:
            Expr.__init__(self, '%s[%d,%d]' % (sym_str, index[0], index[1]))
        elif len(index) == 3:
            Expr.__init__(self, '%s[%d,%d,%d]' % (sym_str, index[0], index[1], index[2]))
        elif len(index) == 4:
            Expr.__init__(self, '%s[%d,%d,%d,%d]' % (sym_str, index[0], index[1], index[2], index[3]))
        elif len(index) == 5:
            Expr.__init__(self, '%s[%d,%d,%d,%d,%d]' % (sym_str, index[0], index[1], index[2], index[3], index[4]))
        else:
            raise SyntaxError("Too many arguments to SymbolExpr constructor. SymbolExpr(symbol_str, [index1], [index2], [index3]")
        
    def getBaseName(self):
        return self.sym_str
    
    def getIndex(self):
        return self.indicies

3.to_cnf()函数,将语句s转换为CNF合取范式,CNF的意思即为几个由“或”相连的字句,通过“与”连接,如:(A | B)&(~A | ~B)。
代码较为复杂,运用了递归求解,可参考资源中to_cnf。

4.pycoSAT()函数,调用了pycosat模块求解可满足语句的模型,即求出语句中命题符号哪些取值可以使得语句为真,若无解,则返回False。具体代码参考资源中pycoSAT。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

19lrf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值