Prolog程序-如何使其工作?

Prolog程序-如何使其工作?,prolog,Prolog,我有这两个项目,但它们没有发挥应有的作用。第一个不带_doubles_2(Xs,Ys)的元素应该表明,如果Ys是在Xs中出现的没有重复的元素列表,那么这是真的。Ys中的元素与Xs的顺序相反,保留第一个重复值。例如,如果没有双精度,则打印X=[6,5,4,3,2,2,1],而打印false without_doubles_2([],[]). without_doubles_2([H|T],[H|Y]):- member(H,T),!,

我有这两个项目,但它们没有发挥应有的作用。第一个不带_doubles_2(Xs,Ys)的元素应该表明,如果Ys是在Xs中出现的没有重复的元素列表,那么这是真的。Ys中的元素与Xs的顺序相反,保留第一个重复值。例如,如果没有双精度,则打印X=[6,5,4,3,2,2,1],而打印false

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([],[]).
您对的调用始终失败,因为您的参数顺序错误:

delete(+List1, @Elem, -List2)
所以不是

delete(H, T, T1)
你想要

delete(T, H, T1)
使用swi prolog解释器的跟踪功能查找类似的错误很简单-只需输入
trace.
即可开始跟踪模式,输入谓词,然后查看解释器正在执行的操作。在这种情况下,您会看到失败来自
delete
语句

还请注意,您可以重写谓词,忽略成员检查,从而忽略第三个子句,因为
delete([1,2,3],9001,[1,2,3])
的计算结果为true-如果元素不在列表中,则结果与输入相同。因此您的谓词可能如下所示(名称因懒散而缩短):

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

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


deleteV/2可以使用库():

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

测试:

编辑更好,来自ssBarBee

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

添加setof作为删除双精度项的备选方案。
%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
?- subtract("carlo","aeiou",L), format('~s',[L]).
crl
L = [99, 114, 108].
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].
?- setof(X,member(X,[1,2,2,5,3,2]),L).
L = [1, 2, 3, 5].