码迷,mamicode.com
首页 > 其他好文 > 详细

Prolog

时间:2020-05-01 16:41:15      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:man   符号   html   表达   属性   简单   sdn   支持   blog   

Prolog简介

部分资料来自于:

http://www.ruanyifeng.com/blog/2019/01/prolog.html
https://blog.csdn.net/laoyao_legend/article/details/84870827

Prolog是一款面向逻辑问题的编程软件(不是离散要求的话,我估计我到死都不会接触这一款)

比如,"苏格拉底是人,人都会死,所以苏格拉底会死"这一类的问题。

只要给定事实和规则,它会自动分析其中的逻辑关系,然后允许用户通过输入和查询,完成复杂的逻辑运算。

(底层估计是强连通分量或者暴力枚举的实现吧,类似于2-SAT问题?不纠结,用就完事了)

运行环境 SWI-Prolog

https://www.swi-prolog.org/

基本框架

运行模块

这是在程序运行阶段,你要进行输入,输入的是命令

技术图片

脚本编辑模块

这是在程序运行之前所要预加载的脚本,你在其中要写定逻辑规则和事实,作为运行基础

技术图片


语法部分

基本格式

开头以"?-"作为命令提示符,表示某个程序的开始

所有语句均以"."作为结束标志

单独语句中有多个命令用","分隔

退出可使用halt命令

输入输出

1)输出语句:write()

下面展示的是经典程序

?- write("Hello, world").
Hello, world!
true.

注意为什么会有多打印个true呢?

Prolog中的命令本身就是一个表达式,命令完成以后,会返回值,并且显示出来

2)换行命令nl:

?- write(‘Hello,‘), nl, write(‘world‘).
Hello,
world
true.

3)输入语句read(变量名)

后面具体脚本在谈怎么用

变量&常量

变量和常量规则很简单:小写字母开头的字符串,就是常量;大写字母开头的字符串,就是变量

?- write(abc).
abc
true.

?- Abc=1,write(Abc).
1
Abc = 1.

关系

两个对象之间的关系,使用括号表示。比如,Jack 的朋友是 Peter,写成

friend(jack, peter).

关系名(A,B)值A对于B是什么/A是B的什么

这里仅代表单向关系, 如果表示双向关系

friend(jack,prter).
friend(peter,jack).

如果括号里面只有一个参数,就表示对象拥有该属性,比如 Jack 是男性,写成male(jack).

规则

规则是推理方法,即如何从一个论断得到另一个论断。

friend(X, Y):-friend(Y,X).

长得比较有内涵的符号":-"表示推理关系

上面代码中,X和Y都是大写,表示这是两个变量。

含义是只要右边的表达式friend(Y, X)为true,那么左边的表达式friend(X, Y)也为true。

因此,根据这条规则,friend(Jack, Peter)就可以推理得到friend(Peter, Jack)。

如果一条规则取决于多个条件,可以使用逗号分隔,如

mother(X, Y) :- child(Y,X), female(X).

注意在Prolog中,符号"+"进行表示

以及在规则设定可以面向多元如,color(A,B,C),differ(A,B,C,D)

在具体编程中,

关系的声明一般使用常量,表示具体的内容满足什么属性。而规则一般使用的是变量,表示抽象出来的对象应有什么属性

当你进行查询的时候,计算机无非是尝试对规则下抽象对象赋以具体值,也就是求抽象对象的可行解

查询

Prolog支持查询已经设定的条件

比如我们在脚本里面写了friend这个规则,我们就可以进行查询

如:查询john有多少个朋友

?- friend(john, Who).
Who = julia ;
Who = jack.

注意如果有多种情况,可以键入“;”查看下一组赋值情况

Who是抽象的,它具体是多少,计算机尝试去给它赋具体值,julia是一个可行解,jack也是一个可行解,它就会输出

函数listing(关系),用于列出所有使关系的元素

如:

?- listing(friend).
friend(john, julia).
friend(john, jack).
friend(julia, sam).
friend(julia, molly).
true.

例子:

技术图片

注意:prolog不支持中文,我在Nodepad++上进行编辑,实际脚本没有以下中文批注

/*
作者:tsy
@Written by tsy

建模思路分析:
我们要找到凶手
这一逻辑问题要落脚于建立正确的匹配关系,即谁拥有什么物品,在哪个房间
Prolog的编程要求我们区分清楚抽象对象和具体对象,那我们如何选定嘞?
当我们讨论什么物品,还是什么房间的时候,我们论述的展开都是建立在“人”之上的,
即我们可以理解成拥有什么物品的人,在什么房间的人,论述的主体始终离不开“人”
所以我们要将物品对应的人,以及房间对应的人,抽象出来,作为变量(大写),求解的正是这些	变量的解情况
而这些可行解应该从具体的人中进行选择,故人名应该看作常量(小写)
*/

//前置条件(1):三男三女,均为常量
man(george).
man(john).
man(robert).
woman(barbara).
woman(christine).
woman(yolanda).

person(X):-man(X).
person(X):-woman(X).

//抽象的事物与具体的人只能一一建立匹配关系,即所有解不能出现相同的
differ(A,B,C,D,E,F):-
person(A),person(B),person(C),person(D),person(E),person(F),
\+A=B,\+A=C,\+A=D,\+A=E,\+A=F,
\+B=C,\+B=D,\+B=E,\+B=F,
\+C=D,\+C=E,\+C=F,
\+D=E,\+D=F,
\+E=F.

//前置条件(2)&&前置条件(3):

murderer(X):-
differ(Bathroom,Diningroom,Kitchen,Livingroom,Pantry,Study),
differ(Bag,Firearm,Gas,Knife,Poison,Rope),

//线索一:厨房里面是一个男人,里面的凶器不是绳索、刀子、包、毒药
man(Kitchen),
\+Kitchen=Rope,
\+Kitchen=Knife,
\+Kitchen=Bag,
\+Kitchen=Firearm,

//线索二:Barbara 和 Yolanda 在浴室和书房,好好理解这句话的意思,我一开始搞错了
woman(Bathroom), woman(Study), 
\+Bathroom=christine, \+Study=christine, 
\+Diningroom=barbara, \+Kitchen=barbara, 
\+Livingroom=barbara, \+Pantry=barbara,
\+Diningroom=yolanda, \+Kitchen=yolanda, 
\+Livingroom=yolanda, \+Pantry=yolanda,

//线索三:带包的那个人不是 Barbara 和 George,也不在浴室和饭厅
\+Bag=barbara,
\+Bag=george,
\+Bag=Bathroom,
\+Bag=Diningroom,

//线索四:书房里面是一个带绳子的女人
woman(Rope),
Rope=Study,

//线索五:起居室里面那件凶器,与 John 或 George 在一起。注意John和George都是男人,故可将后半句转义。
man(Livingroom),
\+Livingroom=robert,

//线索六:刀子不在饭厅
\+Knife=Diningroom,

//线索七:书房和食品储藏室里面的凶器,没跟 Yolanda 在一起
\+Study=yolanda,
\+Pantry=yolanda,

//线索八:George所在的那间屋子有火枪
Firearm=george,

//线索九:Boddy 先生死在食品储藏室里,那里的凶器是煤气
Pantry=Gas,
X=Gas.

运行结果

技术图片

我这里键入了分号让他输出下一组可行解

结果flase,说明christine是唯一的可行解

注意可能脚本编译会warning:Poison这个没有添加任何约束条件,但代码能跑

为了美观我在脚本里面加了Poison=Poison

Prolog

标签:man   符号   html   表达   属性   简单   sdn   支持   blog   

原文地址:https://www.cnblogs.com/et3-tsy/p/12813714.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!