强制Prolog选择变量的唯一值 [英] Force Prolog to choose unique values of variables

查看:98
本文介绍了强制Prolog选择变量的唯一值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我是Prolog的新手,请原谅,如果这很琐碎,但是我似乎找不到合适的优雅答案.我正在尝试在 learnprolognow.org ,练习2.4(填字游戏).

OK I am new to Prolog, so excuse me if this is something trivial, but I can't seem to find a proper elegant answer to this. I am trying to work out the exercise here on learnprolognow.org, exercise 2.4 (the crossword).

该练习提供了以下事实:

The exercise provides these facts:

   word(astante,  a,s,t,a,n,t,e). 
   word(astoria,  a,s,t,o,r,i,a). 
   word(baratto,  b,a,r,a,t,t,o). 
   word(cobalto,  c,o,b,a,l,t,o). 
   word(pistola,  p,i,s,t,o,l,a). 
   word(statale,  s,t,a,t,a,l,e).

我想出的解决每个单词的填字游戏位置的方法是:

And the solution I came up with to solve the crossword placement of each word is this:

crossword(V1, V2, V3, H1, H2, H3) :-
   word(V1, V1a, V1bH1b, V1c, V1dH2b, V1e, V1fH3b, V1g), 
   word(V2, V2a, V2bH1d, V2c, V2dH2d, V2e, V2fH3d, V2g), 
   word(V3, V3a, V3bH1f, V3c, V3dH2f, V3e, V3fH3f, V3g), 
   word(H1, H1a, V1bH1b, H1c, V2bH1d, H1e, V3bH1f, H1g), 
   word(H2, H2a, V1dH2b, H2c, V2dH2d, H2e, V3dH2f, H2g), 
   word(H3, H3a, V1fH3b, H3c, V2fH3d, H3e, V3fH3f, H3g).

V1aV1g等是每个单词的字符,而V1bH1bV3fH3f是填​​字游戏中单词之间的共同字符.

With V1a to V1g etc. being the characters of each word, and the V1bH1b to V3fH3f being the characters in common between words in the crossword.

该解决方案似乎可行,但是结果产生了重复的值,第一个结果是:

The solution seems to work, however the result is producing duplicate values, with the first result being:

?- crossword(V1, V2, V3, H1, H2, H3).
V1 = astante,
V2 = baratto,
V3 = statale,
H1 = astante,
H2 = baratto,
H3 = statale .

如何强制Prolog具有V1 \= V2 \= V3 \= H1 \= H2 \= H3? 如果我一个接一个地做它们,我将需要120个排列,所以必须有一种更快的方法,这是初学者的练习,所以我一定会缺少一些东西.

How can I force Prolog to have V1 \= V2 \= V3 \= H1 \= H2 \= H3 ? If I do them individually one by one I will need 120 permutations, so there must be a quicker way, and this is a beginners exercise so I must be missing something.

我发现了这相似的问题,但提供的答案似乎太复杂了,我希望有一种更简单的方法.我在Ubuntu上使用swi-prolog,以防万一.

I found this similar question, but the answers provided seem so complicated, I hope there is a simpler way. I am using swi-prolog on Ubuntu, just in case it matters.

谢谢.

推荐答案

使用alldif/1定义如下:

alldif([]).
alldif([E|Es]) :-
   maplist(dif(E), Es),
   alldif(Es).

甚至可以用于最一般的查询:

Which can be used even for the most general query:

?- alldif(Es).
Es = [] ;
Es = [_G1924] ;
Es = [_G2061, _G2064],
dif(_G2061, _G2064) ;
Es = [_G2163, _G2166, _G2169],
dif(_G2163, _G2169),
dif(_G2163, _G2166),
dif(_G2166, _G2169) ;
Es = [_G2309, _G2312, _G2315, _G2318],
dif(_G2309, _G2318),
dif(_G2309, _G2315),
dif(_G2309, _G2312),
dif(_G2315, _G2318),
dif(_G2312, _G2315),
dif(_G2312, _G2318) ...

目标maplist(dif(E),Es)的含义可以通过查看答案得到最好的理解:

The meaning of the goal maplist(dif(E),Es) is best understood by looking at the answers:

?- maplist(dif(E),Es).
Es = [] ;
Es = [_G1987],
dif(E, _G1987) ;
Es = [_G2040, _G2043],
dif(E, _G2043),
dif(E, _G2040) ;
Es = [_G2093, _G2096, _G2099],
dif(E, _G2099),
dif(E, _G2096),
dif(E, _G2093) ;
Es = [_G2146, _G2149, _G2152, _G2155],
dif(E, _G2155),
dif(E, _G2152),
dif(E, _G2149),
dif(E, _G2146) ...

也就是说,Es是与E不同的所有元素的列表.目标 maplist(dif(E),[ A,B,C])将第一个元素(在本例中为dif(E))与列表中的每个元素组合在一起.因此dif(E,A), dif(E,B), dif(E,C).

That is, Es is a list of elements that are all different to E. The goal maplist(dif(E),[A,B,C]) combines the first element (in this case dif(E)) with each element of the list. Thus dif(E,A), dif(E,B), dif(E,C).

这篇关于强制Prolog选择变量的唯一值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆