相关疑难解决方法(0)

不同/ 2 - 是否存在纯粹的,确定的定义?

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/2non_member/2几乎是1从声明的观点完美的,它产生于特定查询的冗余解决方案,并选择留点周围.

什么是改进的定义(以纯粹的方式可能使用if_/3(=)/3),使得完全相同的解决方案集被描述different/2但至少对于地面查询是确定的(因此不会留下任何无用的选择点)并且省略(如有可能)任何多余的答案?


1 实际上,different([a|nonlist],[]), different([],[b|nonlist])成功了.它同样可能失败.所以两者都失败的解决方案很好(甚至可能更精细).

prolog prolog-dif logical-purity

33
推荐指数
7
解决办法
791
查看次数

以系统的方式报告 Prolog 中查询失败的“原因”

我正在 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 first-order-logic

6
推荐指数
1
解决办法
336
查看次数

在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 zebra-puzzle

4
推荐指数
1
解决办法
521
查看次数

为什么我无法通过Prolog获得Ship Puzzle的答案?

我需要使用Prolog来解决Ship Puzzle问题.这是事实.

有5艘船.

  1. 希腊船只在六点离开并运载咖啡.
  2. 中间的船有一个黑色的烟囱.
  3. 英国船只在九点发车.
  4. 带有蓝色烟囱的法国船位于运载咖啡的船的左侧.
  5. 在运载可可的船的右边是一艘前往马赛的船.
  6. 巴西船正驶往马尼拉.
  7. 在运载大米的船旁边是一艘带有绿色烟囱的船.
  8. 前往热那亚的一艘船在五点离开.
  9. 这艘西班牙船在七点离开,位于前往马赛的船的右侧.
  10. 带红色烟囱的船前往汉堡.
  11. 在七号船离开的旁边是一艘带有白色烟囱的船.
  12. 边境上的船载着玉米.
  13. 带有黑色烟囱的船在八点落叶.
  14. 运载玉米的船停泊在运载大米的船旁边.
  15. 前往汉堡的船只在六点离开.

哪艘船去了赛义德港?哪艘船载茶?

我搜索互联网寻找答案,但我找不到任何答案.所以我提到'斑马拼图',因此我安排了这个问题的代码.所以这是我的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)

但是当我运行该程序时,它会说"假".
那我怎么解决这个问题呢?
谢谢

prolog zebra-puzzle

3
推荐指数
1
解决办法
509
查看次数

了解序言中反向列表的这种实现

我已经编写了以下小型知识库来反转给定列表,

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

3
推荐指数
2
解决办法
447
查看次数

如何为Prolog使用有效的调试器/跟踪

我是Prolog的新手(开始学习两周),涉及汉密尔顿路径的作业会使我发疯,尤其是在调试问题时。在haskell中,您可以执行调试跟踪,以便每次运行函数时,它都会吐出我想要的任何值,因此我知道输入的内容和输出的内容,并猜测数字在哪里。

在Prolog中会存在类似的东西吗?用谷歌搜索,但是我做错了,因为到目前为止我还没有运气。威尔

debugging trace prolog

3
推荐指数
1
解决办法
2472
查看次数

选择在序言中排序

我是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 program-slicing

3
推荐指数
1
解决办法
1346
查看次数

爱因斯坦之谜使用Prolog

我正试图用Prolog解决爱因斯坦之谜.当我试图通过房屋(Hs)运行时,它显示没有.任务是

  1. 英国人住在红房子里.
  2. 瑞典人将狗作为宠物.
  3. 丹麦人喝茶.
  4. 温室位于白宫的左侧.
  5. 温室的主人喝咖啡.
  6. 吸烟Pall Mall的老板饲养鸟类.
  7. 黄屋的主人吸烟了登喜路.
  8. 住在中心的老板喝牛奶.
  9. 挪威人居住在第一所房子里.
  10. 抽吸混合物的主人生活在养猫的旁边.
  11. 保持马的主人住在吸烟者的旁边.
  12. 吸烟的主人喝啤酒.
  13. 德国人抽烟王子.
  14. 挪威人住在蓝屋旁边.
  15. 抽吸混合物的主人生活在喝水的人旁边.
    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 program-slicing zebra-puzzle

2
推荐指数
1
解决办法
417
查看次数

Prolog中的爱因斯坦之谜

我正试图用Prolog解决爱因斯坦之谜.任务是

  1. 挪威人居住在第一所房子里.
  2. 英国人住在红楼.
  3. 瑞典有狗作为宠物.
  4. 丹麦人喝茶.
  5. 绿屋位于白宫的左侧.
  6. 住在温室里的男人喝咖啡.
  7. 抽烟Pall Mall的男人饲养鸟类.
  8. 住在黄屋的那个人抽烟了登喜路.
  9. 住在中楼的男人喝牛奶.
  10. 抽烟的人混合生活在有猫的人旁边.
  11. 养马的男人住在吸烟登喜路的旁边.
  12. 抽烟师傅的男人喝啤酒.
  13. 德国人抽烟王子.
  14. 挪威人居住在蓝屋旁边.
  15. 抽烟混合的男人是喝水的邻居.
  16. 有人有一个带鱼的水族馆.

该程序:

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)

prolog zebra-puzzle

1
推荐指数
1
解决办法
562
查看次数