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,…]) 第一个参数 ...
随机推荐
- element-ui里面的table插入多张图片
<el-form-item label="身份证正反面" label-width="120px"> <section v-if="t ...
- 牛顿插值法(c++)
X Y 0.40 0.41075 0.55 0.57815 0.65 0.69675 0.80 0.88811 0.90 1.02652 1.05 1.25382 #include using nam ...
- 作业——10 分布式文件系统HDFS 练习
作业的要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3292 利用Shell命令与HDFS进行交互 以”./bin/dfs ...
- Mac复制粘贴文本时默认使用无格式模式
参考:How to Paste Everything as Plain Text 写文章的时候,用的最多的就是copy和paste了,可是现在Mac和Win默认都是会连格式一起复制,真是逆天,导致每次 ...
- phpstudy apache 服务无法启动
1.找到apache路径 3.打开cmd进入bin文件夹 4.输入 httpd.exe 看报的什么错误即可解决 我的这边是httpd.config 里面配置了个项目文件夹路径,这个文件夹被我删了,导 ...
- C++ Java throw goto
throw goto - 国内版 Binghttps://cn.bing.com/search?FORM=U227DF&PC=U227&q=throw+goto C++ throw 代 ...
- 将AD域漫游用户配置文件放在samba服务器中
书接上回https://www.cnblogs.com/jackadam/p/11448497.html 我们已经将linux服务器设置为域成员,启动samba服务后,已经实现了使用域账号验证,自动创 ...
- jsp 记录
前后端开发好久后,一直没怎么用前端开发了.最近任务比较急,又开始写jsp页面了... 1)jquery.validate.min.js 用法总结 https://www.cnblogs.com/x ...
- 【tensorflow基础】ubuntu-tensorflow可视化工具tensorboard-No dashboards are active for the current data set.
前言 今天基于tensorflow训练一个检测模型,本应看到训练曲线的,却只见到一个文件events.out.tfevents.1570520647.hostname,后来发现这个文件可以查看训练曲线 ...
- dataTable.NET的column index的不同定義
dataTable.NET是一個jQuery的plug in 第三方的library, 用來實現web page中table的interaction controls, 另外最近有在用的還有Teler ...