使用kanren的斑马问题

斑马问题

题目

 5 个不同国家(英国、西班牙、日本、意大利、挪威)且工作各不相同(油漆工、摄影师、外交官、小提琴家、医生)的人分别住在一条街上的 5 所房子里,  
每所房子的颜色不同(红色、白色、蓝色、黄色、绿色),每个人都有自己养的不同宠物(狗、蜗牛、斑马、马、狐狸),喜欢喝不同的饮料(矿泉水、牛奶、茶、橘子汁、咖啡)。

根据以下提示,你能告诉我哪所房子里的人养斑马,哪所房子里的人喜欢喝矿泉水吗?

1. 英国人住在红色的房子里
2. 西班牙人养了一条狗
3. 日本人是一个油漆工
4. 意大利人喜欢喝茶
5. 挪威人住在左边的第一个房子里
6. 绿房子在白房子的右边
7. 摄影师养了一只蜗牛
8. 外交官住在黄房子里
9. 中间那个房子的人喜欢喝牛奶
10. 喜欢喝咖啡的人住在绿房子里
11. 挪威人住在蓝色的房子旁边
12. 小提琴家喜欢喝橘子汁
13. 养狐狸的人所住的房子与医生的房子相邻
14. 养马的人所住的房子与外交官的房子相邻

参考资料:[斑马难题-百度百科](https://baike.baidu.com/item/%E6%96%91%E9%A9%AC%E9%9A%BE%E9%A2%98/3709972?fr=aladdin)

 代码

from kanren import run, eq, membero, var, conde  # kanren一个描述性Python逻辑编程系统
from kanren.core import lall  # lall包用于定义规则
import time
def left(q, p, list):
    return membero((q, p), zip(list, list[1:]))
def right_of(q, p, list):
    return left(p, q, list)
def next_to(q, p, list):
    return conde([left(q, p, list)], [right_of(q, p, list)])
class Agent:
    """
    推理智能体.
    """
    def __init__(self):
        """
        智能体初始化.
        """
        self.units = var()  # 单个unit变量指代一座房子的信息(国家,工作,饮料,宠物,颜色)
        # 例如('英国人', '油漆工', '茶', '狗', '红色')即为正确格式,但不是本题答案
        # 请基于给定的逻辑提示求解五条正确的答案
        self.rules_zebraproblem = None  # 用lall包定义逻辑规则
        self.solutions = None  # 存储结果
    def define_rules(self):
        """
        定义逻辑规则.
        """
        self.rules_zebraproblem = lall(
            (eq, (var(), var(), var(), var(), var()), self.units),
            # self.units共包含五个unit成员,即每一个unit对应的var都指代一座房子(国家,工作,饮料,宠物,颜色)
            # 各个unit房子又包含五个成员属性: (国家,工作,饮料,宠物,颜色)
            (membero, ('英国人', var(), var(), var(), '红色'), self.units),  # Clue 1
            (membero, ('西班牙人', var(), var(), '狗', var()), self.units),  # Clue 2
            (membero, ('日本人', '油漆工', var(), var(), var()), self.units),  # Clue 3
            (membero, ('意大利人', var(), '茶', var(), var()), self.units),  # Clue 4
            (eq, (('挪威人', var(), var(), var(), var()), var(), var(), var(), var()), self.units),  # Clue 5
            (right_of, (var(), var(), var(), var(), '绿色'), (var(), var(), var(), var(), '白色'),self.units),
            # Clue 6
            (membero, (var(), '摄影师', var(), '蜗牛', var()), self.units),  # Clue 7
            (membero, (var(), '外交官', var(), var(), '黄色'), self.units),  # Clue 8
            (eq, (var(), var(), (var(), var(), '牛奶', var(), var()), var(), var()), self.units),  # Clue 9
            (membero, (var(), var(), '咖啡', var(), '绿色'), self.units),  # Clue 10
            (next_to, ('挪威人', var(), var(), var(), var()), (var(), var(), var(), var(), '蓝色'), self.units),
            # Clue 11
            (membero, (var(), '小提琴家', '橘子汁', var(), var()), self.units),  # Clue 12
            (next_to, (var(), var(), var(), '狐狸', var()), (var(), '医生', var(), var(), var()), self.units),
            # Clue 13
            (next_to, (var(), var(), var(), '马', var()), (var(), '外交官', var(), var(), var()), self.units), # Clue 14
            (membero, (var(), var(), '矿泉水', var(), var()), self.units),  # Clue 15
            (membero, (var(), var(), var(), '斑马', var()), self.units),  # Clue 16
        )
    def solve(self):
        """
        规则求解器
        return: 斑马规则求解器给出的答案,共包含五条匹配信息,解唯一.
        """

        self.define_rules()
        self.solutions = run(0, self.units, self.rules_zebraproblem)
        return self.solutions
if __name__ == '__main__':
    agent = Agent()
    solutions = agent.solve()
    # 提取解释器的输出
    output = [house for house in solutions[0] if '斑马' in house][0][4]
    print('\n{}房子里的人养斑马'.format(output))
    output = [house for house in solutions[0] if '矿泉水' in house][0][4]
    print('{}房子里的人喜欢喝矿泉水'.format(output))
    # 解释器的输出结果展示
    for i in solutions[0]:
        print(i)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

韩敬之

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

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

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

打赏作者

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

抵扣说明:

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

余额充值