Prolog,列表中元素Y之前的X元素

时间:2016-06-22 11:25:33

标签: prolog

我将编写谓词,只有当X出现在Y列表L

之前时才会生成iff
before(L, X, Y) :-
    nth1(PX, L, X),
    nth1(PY, L, Y),
    PX < PY.  

上面,你可以看到我的解决方案。你怎么看待这件事 ?

谈到我的具体问题:
当至少有一对Y跟随X时,我的谓词返回true。如何定义谓词,使每个对都成立?

2 个答案:

答案 0 :(得分:4)

您展示的解决方案适用于&#34;如果存在&#34;案例,但在某种程度上是必要的。也就是说,它有点像翻译成Prolog的C程序。势在暗示意味着您使用编程语言告诉计算机,执行哪些步骤以实现结果。

为了更具说明性或关系性,你的&#34;存在&#34;解决方案可以很好地表达为DCG:

...

(注意:您可以在Prolog中有一个名为X的谓词,此处显示。)这描述了列表中YX的关系。它没有描述要执行的步骤,而是描述序列中YX的关系。此解决方案已显示before on SO

遵循这种方法(我们描述YX的关系),表达所有Y的所有before_all(X, Y) --> { dif(X,Y) }, any_sequence_but(Y), [X], any_sequence_but(Y), [Y], any_sequence_but(X). any_sequence_but(_) --> []. any_sequence_but(Y) --> [X], { dif(X,Y) }, any_sequence_but(Y). 之前的一种方式(不一定是唯一的方法) 1}}将是:

?- phrase(before_all(X,Y), [b,a,b,c,a,b,d]).
X = b,
Y = d ;
X = a,
Y = d ;
X = b,
Y = d ;
X = c,
Y = d ;
X = a,
Y = d ;
X = b,
Y = d ;
false.

?-

这产生了这样的解决方案:

{{1}}

答案 1 :(得分:0)

如果条件应该适用于所有对,则条件应该至少保持一对,而任何对的条件不应该为真。

我冒昧地将您的before/3重命名为beforeSome/3

beforeSome(L, X, Y) :-
    nth1(PX, L, X),
    nth1(PY, L, Y),
    PX < PY.

beforeAll(L, X, Y) :-
    beforeSome(X,Y),
    not(beforeSome(L, Y, X)).

产生了预期的结果:

?- beforeAll([1,2,3,1,4,5], 1, 4).
true.

?- beforeAll([1,2,3,1,4,5], 1, 2).
false.

请注意,使用nth1/3会阻止它与未实例化的变量一起使用。换句话说,beforeAll([1,2,3,1,4,5], X, Y).false

beforeSome/3的更好实现类似于

beforeSome([X|T], X, Y) :-
    member(Y, T).

beforeSome([_|T], X, Y) :-
    beforeSome(T, X, Y).

% no change needed, but repeated here for completeness' sake
beforeAll(L, X, Y) :-
    beforeSome(X,Y),
    not(beforeSome(L, Y, X)).