2012-03-13 3 views
0

Я пытаюсь сделать программу в прологе, что будет делать что-то вроде этого:Пролог перечисляет разница

diffSet([a,b,c,d], [a,b,e,f], X). 
X = [c,d,e,f] 

Я написал:

diffSet([], _, []). 
diffSet([H|T1],Set,Z):- member(Set, H), !, diffSet(T1,Set,Z). 
diffSet([H|T], Set, [H|Set2]):- diffSet(T,Set,Set2). 

Но таким образом я могу получить только элементы первый список. Как я могу извлечь элементы из второго?

@edit: элемент проверки, если H находится в Set

member([H|_], H). 
member([_|T], H):- member(T, H). 

ответ

2

Существует builtin, что удалить элементы из списка:

diffSet([], X, X). 

diffSet([H|T1],Set,Z):- 
member(H, Set),  % NOTE: arguments swapped! 
!, delete(T1, H, T2), % avoid duplicates in first list 
delete(Set, H, Set2), % remove duplicates in second list 
diffSet(T2, Set2, Z). 

diffSet([H|T], Set, [H|Set2]) :- 
diffSet(T,Set,Set2). 
+0

Почему вы удаляете дубликаты из второго списка, но не с первого? – false

+0

@false: delete (T1, H, T2) должен работать, я думаю – CapelliC

0

Сознательно избегая встроенные модули для этого, что @ chac упоминает, это неэлегантный способ, который выполняет эту работу.

notcommon([], _, []). 

notcommon([H1|T1], L2, [H1|Diffs]) :- 
    not(member(H1, L2)), 
    notcommon(T1, L2, Diffs). 

notcommon([_|T1], L2, Diffs) :- 
    notcommon(T1, L2, Diffs). 

alldiffs(L1, L2, AllDiffs) :- 
    notcommon(L1, L2, SetOne), 
    notcommon(L2, L1, SetTwo), 
    append(SetOne, SetTwo, AllDiffs). 


    ? alldiffs([a,b,c,d], [a,b,e,f], X). 
    X = [c, d, e, f] . 
0

Или использование только встроенных модулей. если вы хотите просто выполнить работу:

notcommon(L1, L2, Result) :- 

    intersection(L1, L2, Intersec), 
    append(L1, L2, AllItems), 
    subtract(AllItems, Intersec, Result). 

    ?- notcommon([a,b,c,d], [a,b,e,f], X). 
    X = [c, d, e, f]. 
Смежные вопросы