2009-10-06 3 views
6

Я пытаюсь реализовать процедуру разметки списка в прологе. По какой-то причине следующий сбой:Процедура разницы в списках прологов

difference(Xs,Ys,D) :- difference(Xs,Ys,[],D). 
difference([],_,A,D) :- D is A, !. 
difference([X|Xs],Ys,A,D) :- 
    not(member(X,Ys)), 
    A1 is [X|A], 
    difference(Xs,Ys,A1,D). 

При попытке:

?- difference([1,2],[],D). 

Я получаю эту ошибку:

ERROR: '.'/2: Type error: `[]' expected, found `1' ("x" must hold one character) 
^ Exception: (10) _L161 is [2|1] ? 

ответ

9

Ваше использование A1 является [X | A] неверным. Предикат is используется только для арифметики. Btw, SWI-Prolog имеет встроенный вычтите предиката:

1 ?- subtract([1,2,3,a,b],[2,a],R). 
R = [1, 3, b]. 

2 ?- listing(subtract). 
subtract([], _, []) :- !. 
subtract([A|C], B, D) :- 
     memberchk(A, B), !, 
     subtract(C, B, D). 
subtract([A|B], C, [A|D]) :- 
     subtract(B, C, D). 

true. 

Является ли это то, что вам нужно?

1

Использование найти все решение становится очевидным:

difference(Xs,Ys,D) :- 
    findall(X,(member(X,Xs),not(member(X,Ys))),D). 
2
minus([H|T1],L2,[H|L3]):- 
    not(member(H,L2)), 
    minus(T1,L2,L3). 
minus([H|T1],L2,L3):- 
    member(H,L2), 
    minus(T1,L2,L3). 
minus([],_,[]). 

minus([1,2,3,4,3], [1,3], L). 

output: L=[2,4] 
2
always (subtructLists(List, [Head|Rest], Result): - 
     ( 
      delete_element(Head, List, Subtructed) 
     , ! 
     , subtructLists(Subtructed, Rest, Result) 
     ) ; (
      subtructLists(List, Rest, Result) 
     ) 
). 

always (subtructLists(List, [], List)). 

always(delete_element(X, [X|Tail], Tail)). 

always(delete_element(X, [Y|Tail1], [Y|Tail2]): - 
     delete_element(X, Tail1, Tail2) 
). 
Смежные вопросы