python逻辑编程之kanren
https://github.com/logpy/logpy
https://pypi.org/project/kanren/
https://www.yiibai.com/ai_with_python/ai_with_python_logic_programming.html
kanren
python逻辑编程
示例:
KANEN是关系的表达式和满足他们的价值的搜索。下列代码就是逻辑编程的"Hello, world!" ,最简单的示例。他请求一个数 x,如x ==5
>>> from kanren import run, eq, membero, var, conde
>>> x = var()
>>> run(1, x, eq(x, 5))
(5,)
多个变量和多个目标可以同时使用。下列代码请求一个数x,如 x==z,同时z==3
>>> z = var()
>>> run(1, x, eq(x, z),
eq(z, 3))
(3,)
KANN使用统一模式匹配的高级形式来匹配表达式树。下列代码请求一个数 X,如(1, 2)=(1,x)。
>>> run(1, x, eq((1, 2), (1, x)))
(2,)
前面的例子中使用的 eq,表述的是两个表达式相等。membero(item, coll)
表示 item
是 coll
集合中的一个成员。下面例子使用 两次 membero去请求 x 的2个值,
>>> run(2, x, membero(x, (1, 2, 3)), # x is a member of (1, 2, 3) #x是(1,2,3)的成员之一
membero(x, (2, 3, 4))) # x is a member of (2, 3, 4) #x是(2,3,4)的成员之一
#2 表示求两个解,则,变量x,可能的解为 (2,3)
(2, 3)
逻辑变量
下面例子中,z = var()
创建一个逻辑变量. 您还可以选择为变量命名,以方便后面调试:
>>> z = var('test')
>>> z
~test
也可以用 vars()
带一个整形参数一次创建一组逻辑变量:
>>> a, b, c = vars(3)
>>> a
~_1
>>> b
~_2
>>> c
~_3
Representing Knowledge
知识表达
kanren存储两个条件之间的状态关系的数据。
kanren stores data as facts that state relationships between terms.、
下面代码创建一个亲缘关系,并且使用它来判断谁是 Simpsons家庭的父亲。
The following code creates a parent relationship and uses it to state facts about who is a parent of whom within the Simpsons family.
>>> from kanren import Relation, facts
>>> parent = Relation()
>>> facts(parent, ("Homer", "Bart"),
... ("Homer", "Lisa"),
... ("Abe", "Homer")) >>> run(1, x, parent(x, "Bart"))
('Homer',) >>> run(2, x, parent("Homer", x))
('Lisa', 'Bart')
我们可以使用中间变量来进行更复杂的查询。Bart的祖父是谁?
We can use intermediate variables for more complex queries. Who is Bart's grandfather?
>>> y = var()
>>> run(1, x, parent(x, y),
parent(y, 'Bart'))
('Abe',)
我们可以分别表达祖父关系。在这个例子中,我们使用CONDE,一个用于逻辑和/或OR的目标构造函数。
We can express the grandfather relationship separately. In this example we use conde
, a goal constructor for logical and and or.
>>> def grandparent(x, z):
... y = var()
... return conde((parent(x, y), parent(y, z))) >>> run(1, x, grandparent(x, 'Bart'))
('Abe,')
数据结构
kanren 依赖 functions, tuples, dicts, and generators. 可以很容易融入以往的代码。
Extending kanren to other Types
kanren uses Multiple Dispatch and the unification library to support pattern matching on user defined types. Also see unification (wikipedia). Types which can be unified can be used for logic programming. See the project examples for how to extend the collection of unifiable types to your use case.
Install
With pip
or easy_install
pip install kanren
From source
git clone git@github.com:logpy/logpy.git
cd logpy
python setup.py install
Run tests with tox
tox
支持
kanren
supports Python 2.7+ and Python 3.3+ with a common codebase. It is pure Python and requires no dependencies beyond the standard library, toolz
, multipledispatch
, and unification
.
简而言之,它是一种轻量级的依赖。
作者
License
New BSD license. See LICENSE.txt
Motivation
Logic programming is a general programming paradigm. This implementation however came about specifically to serve as an algorithmic core for Computer Algebra Systems in Python and for the automated generation and optimization of numeric software. Domain specific languages, code generation, and compilers have recently been a hot topic in the Scientific Python community. kanren aims to be a low-level core for these projects.
References
- Logic Programming on wikipedia
- miniKanren, a Scheme library for relational programming on which this library is based. More information can be found in the thesis of William Byrd.
- core.logic a popular implementation of miniKanren in Clojure.
如果涉及到某些函数不会用,不知道做啥用的,直接下载源代码,查看里面的各个文件,都有详细的解释。
解决难题
逻辑编程可用于解决许多问题,如8拼图,斑马拼图,数独,N皇后等。在这里,举例说明斑马拼图的变体如下 -
有五间房子。
英国人住在红房子里。
瑞典人有一只狗。
丹麦人喝茶。
绿房子在白房子的左边。
他们在绿房子里喝咖啡。
吸Pall Mall的人有鸟。
吸Dunhill在的人黄色房子里。
在中间的房子里,他们喝牛奶。
挪威人住在第一宫。
那个抽Blend的男人住在猫屋旁边的房子里。
在他们有一匹马的房子旁边的房子里,他们吸Dunhill烟。
抽Blue Master的人喝啤酒。
德国人吸Prince烟。
挪威人住在蓝房子旁边。
他们在房子旁边的房子里喝水,在那里吸Blend烟。
在Python的帮助下解决谁有斑马的问题。
导入必要的软件包 -
from kanren import *
from kanren.core import lall
import time
现在,我们需要定义两个函数 - left()
和next()
来查找哪个房屋左边或接近谁的房子 -
def left(q, p, list):
return membero((q,p), zip(list, list[1:]))
def next(q, p, list):
return conde([left(q, p, list)], [left(p, q, list)])
现在,声明一个变量:houses
,如下 -
houses = var()
需要在lall
包的帮助下定义规则如下。
有5
间房子 -
rules_zebraproblem = lall(
(eq, (var(), var(), var(), var(), var()), houses), #5个var()分别代表 人、烟、饮料、动物、屋子颜色 (membero,('Englishman', var(), var(), var(), 'red'), houses),
(membero,('Swede', var(), var(), 'dog', var()), houses),
(membero,('Dane', var(), 'tea', var(), var()), houses),
(left,(var(), var(), var(), var(), 'green'),
(var(), var(), var(), var(), 'white'), houses),
(membero,(var(), var(), 'coffee', var(), 'green'), houses),
(membero,(var(), 'Pall Mall', var(), 'birds', var()), houses),
(membero,(var(), 'Dunhill', var(), var(), 'yellow'), houses),
(eq,(var(), var(), (var(), var(), 'milk', var(), var()), var(), var()), houses),
(eq,(('Norwegian', var(), var(), var(), var()), var(), var(), var(), var()), houses),
(next,(var(), 'Blend', var(), var(), var()),
(var(), var(), var(), 'cats', var()), houses),
(next,(var(), 'Dunhill', var(), var(), var()),
(var(), var(), var(), 'horse', var()), houses),
(membero,(var(), 'Blue Master', 'beer', var(), var()), houses),
(membero,('German', 'Prince', var(), var(), var()), houses),
(next,('Norwegian', var(), var(), var(), var()),
(var(), var(), var(), var(), 'blue'), houses),
(next,(var(), 'Blend', var(), var(), var()),
(var(), var(), 'water', var(), var()), houses),
(membero,(var(), var(), var(), 'zebra', var()), houses)
)
现在,用前面的约束运行解算器 -
solutions = run(0, houses, rules_zebraproblem)
借助以下代码,可以提取解算器的输出 -
output_zebra = [house for house in solutions[0] if 'zebra' in house][0][0]
以下代码将打印解决方案 -
print ('\n'+ output_zebra + 'owns zebra.')
上述代码的输出如下 -
German owns zebra.
python逻辑编程之kanren的更多相关文章
- python异步编程之asyncio
python异步编程之asyncio 前言:python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病.然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率, ...
- Python 多进程编程之multiprocessing--Pool
Python 多进程编程之multiprocessing--Pool ----当需要创建的子进程数量不多的时候,可以直接利用multiprocessing 中的Process 动态生成多个进程, -- ...
- Python 多进程编程之multiprocessing--Process
Python 多进程编程之multiprocessing 1,Process 跨平台的进程创建模块(multiprocessing), 支持跨平台:windowx/linux 创建和启动 创 ...
- python并发编程之Queue线程、进程、协程通信(五)
单线程.多线程之间.进程之间.协程之间很多时候需要协同完成工作,这个时候它们需要进行通讯.或者说为了解耦,普遍采用Queue,生产消费模式. 系列文章 python并发编程之threading线程(一 ...
- python并发编程之gevent协程(四)
协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...
- python并发编程之asyncio协程(三)
协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...
- python并发编程之multiprocessing进程(二)
python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. 系列文章 python并发编程之threading线程(一) python并 ...
- python并发编程之threading线程(一)
进程是系统进行资源分配最小单元,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.进程在执行过程中拥有独立的内存单元,而多个线程共享内存等资源. 系列文章 py ...
- Python函数式编程之map()
Python函数式编程之map() Python中map().filter().reduce()这三个都是应用于序列的内置函数. 格式: map(func, seq1[, seq2,…]) 第一个参数 ...
随机推荐
- Linux+Tomcat环境下安装SSL证书
1.将申请好的证书(4个文件)文件放入/home/tomcat/apache-tomcat-9.0.12/conf/cert文件夹下2.(或者)将申请好的证书(4个文件)文件放入/home/tomca ...
- centos7---mysql5.7主从复制读写分离
1 分别在两台centos 7系统上安装mysql 5.7 具体的安装步骤可以见此链接,https://blog.csdn.net/qq_15092079/article/details/816292 ...
- 使用建造者模式和Lombok简化代码
在项目开发中,我们经常需要构建对象.常见的做法有getter/setter,或者构造器构建对象. 可能会有人写出类似如下的代码: Company company=new Company(); comp ...
- 基于 Mathematica 的机器人仿真环境(机械臂篇)[转]
完美的教程,没有之一,收藏学习. 目的 本文手把手教你在 Mathematica 软件中搭建机器人的仿真环境,具体包括以下内容(所使用的版本是 Mathematica 11.1,更早的版本可能缺少某些 ...
- 包含MANIFEST.MF的jar可执行应用指定classpath及spring boot应用增量升级打包实现
对于不包含MANIFEST.MF,或jar包中的MANIFEST.MF未指定MainClass的jar,可以通过java命令行选项-classpath指定classpath.但是如果是包含MainCl ...
- 关于Objective-C新增的__kindof关键字
Objective-C随着Xcode 7的升级带来了许多新特性,当然此次更新最最大的就是引入了Objective-C的轻量级泛型,确切地说是Objective-C类的轻量级泛型.除此之外,还有一个小特 ...
- svg的viewport和viewbox
svg中视区重要的概念 1. viewport 视口,相当于显示器屏幕 2. viewbox 视区,相当于在屏幕上截取一小块,放大到整个屏幕,就是特写的效果 3. preserveAspectR ...
- [LeetCode] 117. Populating Next Right Pointers in Each Node II 每个节点的右向指针 II
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- [LeetCode] 482. License Key Formatting 注册码格式化
You are given a license key represented as a string S which consists only alphanumeric character and ...
- 解决ScrollView嵌套百度地图滑动冲突
一.问题描述 scrollview中嵌套百度地图时会出现滑动冲突,地图无法滑动的情况. 二.期望结果 焦点在地图上时,只有地图移动,焦点在地图外部时,可以滑动scrollview. 三.解决方法 自定 ...