different(Xs, Ys) :-
member(X, Xs),
non_member(X, Ys).
different(Xs, Ys) :-
member(Y, Ys),
non_member(Y, Xs).
Run Code Online (Sandbox Code Playgroud)
虽然这个定义使用member/2和non_member/2几乎是1从声明的观点完美的,它产生于特定查询的冗余解决方案,并选择留点周围.
什么是改进的定义(以纯粹的方式可能使用if_/3和(=)/3),使得完全相同的解决方案集被描述different/2但至少对于地面查询是确定的(因此不会留下任何无用的选择点)并且省略(如有可能)任何多余的答案?
1
实际上,different([a|nonlist],[]), different([],[b|nonlist])成功了.它同样可能失败.所以两者都失败的解决方案很好(甚至可能更精细).
我正在 Prolog 中寻找一种方法、模式或内置功能,我可以用它来返回原因,至少就数据库中的谓词而言。当用户在系统中提出查询时,我试图能够说的不仅仅是“那是错误的”。
例如,假设我有两个谓词。 blue/1如果某物是蓝色,则为真;dog/1如果某物是狗,则为真:
blue(X) :- ...
dog(X) :- ...
Run Code Online (Sandbox Code Playgroud)
如果我向 Prolog 提出以下查询并且foo是一只狗,但不是蓝色,Prolog 通常只会返回“false”:
? blue(foo), dog(foo)
false.
Run Code Online (Sandbox Code Playgroud)
我想要的是找出为什么谓词的合取不正确,即使它是带外调用,例如:
? getReasonForFailure(X)
X = not(blue(foo))
Run Code Online (Sandbox Code Playgroud)
如果谓词必须以某种方式编写,我没关系,我只是在寻找人们使用过的任何方法。
迄今为止,我完成此操作并取得了一些成功的方法是以程式化的方式编写谓词,并使用一些辅助谓词来找出事后的原因。例如:
blue(X) :-
recordFailureReason(not(blue(X))),
isBlue(X).
Run Code Online (Sandbox Code Playgroud)
然后实现 recordFailureReason/1 ,以便它始终记住堆栈最深处发生的“原因”。如果查询失败,则发生最深的任何失败都会被记录为失败的“最佳”原因。这种启发式方法在许多情况下都出奇地有效,但确实需要仔细构建谓词才能正常工作。
有任何想法吗?我愿意看看 Prolog 之外是否有专为此类分析而设计的谓词逻辑系统。
我正试图在Prolog中解决爱因斯坦之谜.
我对我编写的程序有困难,基本方法是添加所有约束,让Prolog找出唯一可能的解决方案.
问题是Prolog找到了0个解决方案.我已经隔离了使程序从给定解决方案转到没有解决方案的约束,但我不明白为什么.
/*There are five houses*/
exists(A, list(A,_,_,_,_)).
exists(A, list(_,A,_,_,_)).
exists(A, list(_,_,A,_,_)).
exists(A, list(_,_,_,A,_)).
exists(A, list(_,_,_,_,A)).
middle_house(A, list(_,_,A,_,_)).
first_house(A, list(A,_,_,_,_)).
nextTo(A, B, list(B,A,_,_,_)).
nextTo(A, B, list(_,B,A,_,_)).
nextTo(A, B, list(_,_,B,A,_)).
nextTo(A, B, list(_,_,_,B,A)).
nextTo(A, B, list(A,B,_,_,_)).
nextTo(A, B, list(_,A,B,_,_)).
nextTo(A, B, list(_,_,A,B,_)).
nextTo(A, B, list(_,_,_,A,B)).
/* each statement will be described using the clues
house conatins: Color,Owner, Drinks, Smokes, Pet*/
riddle(Houses):-
/*exists(house(red, englishman, _,_,_),Houses),*/
nextTo(house(_,norwegian,_,_,_), house(blue,_,_,_,_), Houses),
exists(house(_,spanish,_,_, dog), Houses),
exists(house(green, _, coffee, _,_), Houses),
exists(house(_, ukrain, tea,_,_), …Run Code Online (Sandbox Code Playgroud) 我需要使用Prolog来解决Ship Puzzle问题.这是事实.
有5艘船.
- 希腊船只在六点离开并运载咖啡.
- 中间的船有一个黑色的烟囱.
- 英国船只在九点发车.
- 带有蓝色烟囱的法国船位于运载咖啡的船的左侧.
- 在运载可可的船的右边是一艘前往马赛的船.
- 巴西船正驶往马尼拉.
- 在运载大米的船旁边是一艘带有绿色烟囱的船.
- 前往热那亚的一艘船在五点离开.
- 这艘西班牙船在七点离开,位于前往马赛的船的右侧.
- 带红色烟囱的船前往汉堡.
- 在七号船离开的旁边是一艘带有白色烟囱的船.
- 边境上的船载着玉米.
- 带有黑色烟囱的船在八点落叶.
- 运载玉米的船停泊在运载大米的船旁边.
- 前往汉堡的船只在六点离开.
哪艘船去了赛义德港?哪艘船载茶?
我搜索互联网寻找答案,但我找不到任何答案.所以我提到'斑马拼图',因此我安排了这个问题的代码.所以这是我的Prolog代码问题.
exists(A,(A,_,_,_,_)).
exists(A,(_,A,_,_,_)).
exists(A,(_,_,A,_,_)).
exists(A,(_,_,_,A,_)).
exists(A,(_,_,_,_,A)).
rightOf(A,B,(B,A,_,_,_)).
rightOf(A,B,(_,B,A,_,_)).
rightOf(A,B,(_,_,B,A,_)).
rightOf(A,B,(_,_,_,B,A)).
middleShip(A,(_,_,A,_,_)).
lastShip(A,(_,_,_,_,A)).
nextTo(A,B,(B,A,_,_,_)).
nextTo(A,B,(_,B,A,_,_)).
nextTo(A,B,(_,_,B,A,_)).
nextTo(A,B,(_,_,_,B,A)).
nextTo(A,B,(A,B,_,_,_)).
nextTo(A,B,(_,A,B,_,_)).
nextTo(A,B,(_,_,A,B,_)).
nextTo(A,B,(_,_,_,A,B)).
solution(PortSaidShip, TeaCarrier) :-
Shipes = (ship(_,_,_,_,_),ship(_,_,_,_,_),ship(_,_,_,_,_),ship(_,_,_,_,_),ship(_,_,_,_,_)),
exists(ship('Greek',6,'Coffee',_,_),Shipes),
middleShip(ship(_,_,_,_,'Black',_),Shipes),
exists(ship('English',9,_,_,_),Shipes),
rightOf(ship(_,_,'Coffee',_,_),ship('French',_,_,'Blue',_),Shipes),
rightOf(ship(_,_,_,_,'Marseille'),ship(_,_,'Cocoa',_,_),Shipes),
exists(ship('Brazilian',_,_,_,'Manila'),Shipes),
nextTo(ship(_,_,_,'Green',_),ship(_,_,'Rice',_,_),Shipes),
exists(ship(_,5,_,_,'Genoa'),Shipes),
rightOf(ship('Spanish',7,_,_,_),ship(_,_,_,_,'Marseille'),Shipes),
exists(ship(_,_,_,'Red','Hamburg'),Shipes),
nextTo(ship(_,_,_,'White',_),ship(_,7,_,_,_),Shipes),
lastShip(ship(_,_,'Corn',_,_),Shipes),
exists(ship(_,8,_,'Black',_),Shipes),
nextTo(ship(_,_,'Corn',_,_),ship(_,_,'Rice',_,_),Shipes),
exists(ship(_,6,_,_,'Hamburg'),Shipes),
exists(ship(PortSaidShip,_,_,_,'Port Said'),Shipes),
exists(ship(TeaCarrier,_,'Tea',_,_),Shipes).
Run Code Online (Sandbox Code Playgroud)
但是当我运行该程序时,它会说"假".
那我怎么解决这个问题呢?
谢谢
我已经编写了以下小型知识库来反转给定列表,
reverse_list([],[]).
reverse_list([X|L1], [L2|X]) :-
reverse_list(L1, L2).
Run Code Online (Sandbox Code Playgroud)
当前,执行时
reverse_list([a,b,c,d], X).
Run Code Online (Sandbox Code Playgroud)
它产生,
X = [[[[[]|d]|c]|b]|a].
Run Code Online (Sandbox Code Playgroud)
解释为什么会发生将不胜感激。而且,我该如何解决这个问题?
我认为在最后一步L2变为[],在向后传播期间,它变成这样。如何X = [d,c,b,a]使用这种方法的修改来获得类似的输出。
PS:我是Prolog的新手。
我是Prolog的新手(开始学习两周),涉及汉密尔顿路径的作业会使我发疯,尤其是在调试问题时。在haskell中,您可以执行调试跟踪,以便每次运行函数时,它都会吐出我想要的任何值,因此我知道输入的内容和输出的内容,并猜测数字在哪里。
在Prolog中会存在类似的东西吗?用谷歌搜索,但是我做错了,因为到目前为止我还没有运气。威尔
我是Prolog的新手,正在尝试对选择进行排序。这是我所拥有的:
ssort([],[]).
ssort([M|S],L):-min(M,L),remove(M,L,N),ssort(S,N).
min(M,[M]).
min(M,[H,T]):-min(N,T),min2(M,H,N).
min2(A,A,B):-less(A,B).
min2(B,A,B):-not(less(A,B)).
less(A,B):-(A<B).
append([],B,B).
append([H|A],B,[H|AB]):-append(A,B,AB).
remove(X,L,N):-append(A,[X|B],L),append(A,B,N).
Run Code Online (Sandbox Code Playgroud)
但是当我尝试例如
ssort(S,[5,3,1]),write(S).
Run Code Online (Sandbox Code Playgroud)
false无论如何,我都能理解。您能告诉我如何实际排序列表并将结果写入其中S吗?
我正试图用Prolog解决爱因斯坦之谜.当我试图通过房屋(Hs)运行时,它显示没有.任务是
houses(Hs) :-
length(Hs, 5),
member(h(english,_,_,_,red), Hs),
member(h(swede,dog,_,_,_), Hs),
member(h(_,_,_,coffee,green), Hs),
member(h(dane,_,_,tea,_), Hs),
next(h(_,_,_,_,green), h(_,_,_,_,white), Hs),
member(h(_,bird,'Pall Mall',_,_), Hs),
member(h(_,_,'Dunhill',_,yellow), Hs),
Hs = [_,_,h(_,_,_,milk,_),_,_],
Hs = [h(norwegian,_,_,_,_)|_],
next(h(_,horse,_,_,_), h(_,_,'Dunhill',_,_), Hs),
next(h(_,_,blend,_,_), h(_,cat,_,_,_), Hs),
member(h(_,_,'Blue Master',beer,_), Hs),
member(h(german,_,'Prince',_,_), Hs),
next(h(norwegian,_,_,_,_), h(_,_,_,_,blue), Hs),
next(h(_,_,'Blend',_,_), h(_,_,_,water,_), Hs),
member(h(_,fish,_,_,_), Hs).
next(A, B, Ls) :- append(_, [A,B|_], Ls).
next(A, B, Ls) :- append(_, [B,A|_], Ls).
我不知道出了什么问题.谢谢
我正试图用Prolog解决爱因斯坦之谜.任务是
- 挪威人居住在第一所房子里.
- 英国人住在红楼.
- 瑞典有狗作为宠物.
- 丹麦人喝茶.
- 绿屋位于白宫的左侧.
- 住在温室里的男人喝咖啡.
- 抽烟Pall Mall的男人饲养鸟类.
- 住在黄屋的那个人抽烟了登喜路.
- 住在中楼的男人喝牛奶.
- 抽烟的人混合生活在有猫的人旁边.
- 养马的男人住在吸烟登喜路的旁边.
- 抽烟师傅的男人喝啤酒.
- 德国人抽烟王子.
- 挪威人居住在蓝屋旁边.
- 抽烟混合的男人是喝水的邻居.
- 有人有一个带鱼的水族馆.
该程序:
neighbor(Rua):-
length(Rua, 5),
Rua = [casa(_,noruegues,_,_,_)|_],
member(casa(vermelha,ingles,_,_,_),Rua),
member(casa(_,sueco,_,_,cachorros),Rua),
member(casa(_,dinamarques,cha,_,_),Rua),
esquerda(casa(verde,_,_,_,_), casa(branca,_,_,_,_),Rua),
member(casa(verde,_,cafe,_,_),Rua),
member(casa(_,_,_,pallmall,passaros),Rua),
member(casa(amarela,_,_,dunhill,_),Rua),
Rua = [_,_,casa(_,_,leite,_,_),_,_],
ao_lado(casa(_,_,_,blends,_), casa(_,_,_,_,gatos),Rua),
ao_lado(casa(_,_,_,_,cavalos), casa(_,_,_,dunhill,_),Rua),
member(casa(_,_,cerveja,bluemaster,_),Rua),
member(casa(_,alemao,_,prince,_),Rua),
ao_lado(casa(_,noruegues,_,_,_), casa(azul,_,_,_,_),Rua),
ao_lado(casa(_,_,_,blends,_), casa(_,_,agua,_,_),Rua),
member(casa(_,_,_,_,peixes),Rua).
ao_lado([X,Y|_],X, Y).
ao_lado([X,Y|_],Y, X).
ao_lado([_|L],X, Y):-
ao_lado(L, X, Y).
esquerda([A|As], A, E) :-
member2(E, As).
esquerda([_|As], A, E) :-
esquerda(As, A, E).
Run Code Online (Sandbox Code Playgroud)