Prolog程序 - 如何使它工作?

时间:2012-12-17 12:09:39

标签: prolog

我有这两个程序,他们没有按照自己的意愿工作。第一个without_doubles_2(Xs,Ys)应该表明,如果Ys是Xs中出现的元素列表而没有重复,则它是真的。 Ys中的元素与Xs的顺序相反,并保留第一个重复值。例如,without_doubles_2([1,2,3,4,5,6,4,4],X)打印X = [6,5,4,3,2,1]但是,它打印错误。

without_doubles_2([],[]).
without_doubles_2([H|T],[H|Y]):- member(H,T),!,
                                 delete(H,T,T1),
                                 without_doubles_2(T1,Y).

without_doubles_2([H|T],[H|Y]):-    without_doubles_2(T,Y).

reverse([],[]).
reverse([H|T],Y):- reverse(T,T1), addtoend(H,T1,Y).

addtoend(H,[],[H]).
addtoend(X,[H|T],[H|T1]):-addtoend(X,T,T1).


without_doubles_21(X,Z):-  without_doubles_2(X,Y),
                           reverse(Y,Z).

第二个是如何让这个程序使用字符串?它应该从字符串中删除元音并仅打印辅音。

deleteV([H|T],R):-member(H,[a,e,i,o,u]),deleteV(T,R),!.
deleteV([H|T],[H|R]):-deleteV(T,R),!.
deleteV([],[]).

2 个答案:

答案 0 :(得分:2)

您对delete的调用总是失败,因为您的参数顺序错误:

delete(+List1, @Elem, -List2)

所以而不是

delete(H, T, T1)

你想要

delete(T, H, T1)

使用swi-prolog解释器的跟踪功能来查找这样的错误很简单 - 只需输入trace.即可开始跟踪模式,输入谓词,并查看解释器正在执行的操作。在这种情况下,您会看到失败来自delete语句。 The documentation related to tracing can be found here

另请注意,您可以重写省略成员检查的谓词,从而重写第三个子句,因为delete([1,2,3],9001,[1,2,3])的计算结果为true - 如果元素不在列表中,则结果与输入相同。所以你的谓词看起来像这样(由于懒惰而缩短了名字):

nodubs([], []).
nodubs([H|T], [H|Y]) :- delete(T, H, T1), nodubs(T1, Y).

对于第二个问题,您可以使用string_to_list谓词将字符串转换为字符列表(表示为ascii代码)。

至于谓词从字符串中删除vovels,我会像这样实现它(对于这个问题可能有更好的解决方案或者你可以使用的一些内置函数,但我的prolog有些生疏):

%deleteall(+L, +Elems, -R)
%a helper predicate for deleting all items in Elems from L
deleteall(L, [], L).
deleteall(L, [H|T], R) :- delete(L, H, L1), deleteall(L1, T, R).

deleteV(S, R) :-
    string_to_list(S, L),         %create list L from input string
    string_to_list("aeiou", A),   %create a list of all vovels
    deleteall(L, A, RL),          %use deleteall to delete all vovels from L
    string_to_list(R, RL).        %turn the result back into a string

答案 1 :(得分:0)

deleteV / 2可以使用库(lists):

?- subtract("carlo","aeiou",L), format('~s',[L]).
crl
L = [99, 114, 108].

在删除重复项时,我们可以利用sort / 2和select / 3:

nodup(L, N) :-
    sort(L, S),
    nodup(L, S, N).

nodup([], _S, []).
nodup([X|Xs], S, N) :-
    ( select(X, S, R) -> N = [X|Ys] ; N = Ys, R = S ),
    nodup(Xs, R, Ys).

试验:

?- nodup([1,2,3,4,4,4,5,2,7],L).
L = [1, 2, 3, 4, 5, 7].
来自ssBarBee的

编辑更好

?- setof(X,member(X,[1,2,2,5,3,2]),L).
L = [1, 2, 3, 5].