在prolog上列出练习

时间:2014-09-02 20:22:01

标签: list prolog

所以我校园的教授要求我们解决这个问题,但是有点困难,我现在试了2天。无论如何它是:

我给出了一个例如[a,b,c,d,w,n,i,c,k,a,b,c,d,w]的列表,在这个列表中我必须找出是否有"怀疑"子表。子列表被视为"怀疑"如果

1)相同的子列表在开头和结尾,

2)它包含" w",

3)它的长度为5。

我给出的清单有一个"怀疑"子列表。

如果存在可疑子列表,则程序必须返回子列表,或者如果没有,则必须返回[o,k]

欢迎任何想法,非常感谢! (对不起,如果我发布了错误的信息)

修改

所以在得到一些帮助之后是asnwer:

 checkMessage1(L,SL):-
    suspiciousMessage1(L,SL).

checkMessage1(L,[o,k]):-
    not(suspiciousMessage1(L,SL)).

suspiciousMessage1(L,SL):-
    append(SL,Last,L),
    append(_,SL,Last),
    length(SL,5),
    member(w,SL).

3 个答案:

答案 0 :(得分:2)

这是使用DCG的一个很好的例子:

list_suspect(Xs, Ys) :-
   length(Ys, 5),
   phrase(( seq(Ys), ..., seq(Ys) ), Xs),
   phrase((...,"w",...), Ys).

... --> [] | [_], ... .

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

以下是使用append/3的版本:

list_suspect(Xs, Ys) :-
    Ys = [_,_,_,_,_],
    append(Ys,Is, Xs),
    append(_, Ys, Is).
    append("w", _, W), % or: "w" = [C], W = [C|_]
    append(_, W, Ys).

它的可读性更好吗?我想不是。

[o,k]的部分对我来说看起来有点不自然,但它会是:

  list_ret(Xs, Ys) :-
     list_suspect(Xs, Ys).
  list_ret(Xs, Ys) :-
     \+ list_suspect(Xs,_),
     Ys = "ok".

答案 1 :(得分:2)

一个班轮,使用append / 2

suspect(L, S) :-
    length(S, 5), append([S,_,S], L), memberchk(w, S) -> true ; S = [o,k].

编辑如false所示,定义是错误的(缺少steadfastness?):修改后的规则

suspect(L, R) :-
    length(S, 5), append([S,_,S], L), memberchk(w, S) -> S = R ; R = [o,k].

答案 2 :(得分:2)

Prolog是一种声明性语言:根据约束描述解决方案并让引擎完成工作。

我们可以确定列表中的成员资格:

contains( [X|Xs] , X ) :- ! .
contains( [_|Xs] , X ) :- contains(Xs,X) .

我们可以使用内置谓词append/3确定列表第一个元素是否与其最后一个元素相同:

list_starts_and_ends_with_identical( [X|Xs] ) :-
  append( [X|_] , [X] , [X|Xs] )
  .

或者,如果你想自己动手:

list_starts_and_ends_with_identical( [A|Xs] ) :-
  list_ends_with( Xs , A )
  .

list_ends_with( [A]     , A ) .
list_ends_with( [B,C|D] , A ) :-
  list_ends_with( [C|D] , A )
  .

我们可以枚举所需长度的子列表,如下所示:

sublist_of_length( Xs, L , Ys ) :- % to enumerate sublists of the desired length,
  integer(L) ,                     % - validate that the length is an integer, and
  L > 0 ,                          % - validate that the length is positive, and
  length(Ys,L) ,                   % - construct a list of unbound variables of the desired length, and
  sl(Ys,L)                         % - invoke the helper
  .                                %

sl( [X|Xs] , L ) :-                % to enumerate sublists,
  append( L , _ , [X|Xs] )         % - simply get the prefix of the desired length
  .                                %
sl( [_|Xs] , L ) :-                % on backtracking,
  sl( Xs , L )                     % - just recurse down on the tail of the list, discarding the first element.
  .

然后,我们所要做的就是组装部件:

suspect_sublist( Xs , L ) :-                 % the source list Xs contains a suspect sublist L, IF...
  sublist_of_length( Xs , 5 , L ) ,         % - L is a sublist of Xs having length 5, and
  contains( L , w ) ,                        % - L contains the atom 'w', and
  list_starts_and_ends_with_identical( L ) , % - the first element of L is identical to the last.
  .                                          % Easy!