2014-10-21 5 views
0

Я хотел бы написать предикат find_difference([A|B],[P|Q],[C-D|E-F]) найти разницу между списком [A|B] и [P|Q], и дать результат, как [C-D|E-F], C указывает на то, что изменения происходят в N-ом подсписка в то время как D говорит, что изменения произойдет в N-м элементе этого подсписка (изменение в каждом подсписке будет только одним символом). Таким образом, запрос и ожидаемый результат будет как:Пролог в списке

find_difference([[a,b,c],[w,t]],[[a,b,d],[w,s]],X). 
X=[1-3,2-2]. 

может предикат также иметь дело с переменными? Например:

find_difference([[A,B,C],[A,D]],[[A,D,C],[A,S]],X). 
X=[1-2,2-2]. 

заблаговременно за любую помощь, которую вы можете предоставить.

find_difference([],[],1). 
find_difference([A|B],[C|D],E):- 
    ( A=C -> 
     find_difference(B,D,Y), 
     E is Y+1 
    ; find_difference(B,D,E) 
    ). 

Теперь я могу получить только разные значения списка. Но если два списка совпадают, он будет отвечать на неправильный ответ. Кроме того, он не может справиться с переменными.

7 ?- find_difference([A,B,C],[A,B,D],X). 
C = D, 
X = 4. 

Почему это?

+0

Ваш заявленный желаемый результат - это список, но ваша попытка реализации явно имеет целочисленный результат ('E'), а не результат списка. – lurker

+0

Что вы понимаете по разнице? Это не ясно из вашего вопроса. Скорее укажите, какая разница. – false

ответ

0

Вот реализация:

find_difference(LA, LB, LDiffs):- 
    find_difference(LA, LB, 1, 1, LDiffs). 

find_difference([], [], _, _, []). 
find_difference([[]|LA], [[]|LB], Row, _, LDiffs):- 
    succ(Row, NRow), 
    find_difference(LA, LB, NRow, 1, LDiffs). 
find_difference([[Item|ATail]|LA], [[Item|BTail]|LB], Row, Col, LDiffs):- 
    succ(Col, NCol), 
    find_difference([ATail|LA], [BTail|LB], Row, NCol, LDiffs). 
find_difference([[AItem|ATail]|LA], [[BItem|BTail]|LB], Row, Col, [Row-Col|LDiffs]):- 
    AItem\=BItem, 
    succ(Col, NCol), 
    find_difference([ATail|LA], [BTail|LB], Row, NCol, LDiffs). 

Вы следить за текущей «строки» и «столбец» и проверить, соответствует ли каждый элемент из первого списка пункт второго списка. Если он не соответствует, вы добавляете местоположение в третий список.

Первое предложение find_difference/5 является базовым регистром (пустые списки по первому и второму аргументу).

Второе предложение переходит от одного «ряда» к следующему.

Третье предложение проверяет, объединяет ли первый элемент списка заголовков в первом и втором аргументах, в этом случае вы просто увеличиваете «столбец».

Четвертое предложение проверяет, не объединяются ли они, поэтому вы добавляете текущий Row-Col в список «output».

В третьем и четвертом предложениях вы увеличиваете текущий столбец и продолжаете рекурсию.

Пример:

?- find_difference([[a,b,c],[w,t]],[[a,b,d],[w,s]],X). 
X = [1-3, 2-2] 

Ваш второй пример (с использованием uninstantiated переменных) не даст результата вы ожидали:

?- find_difference([[A,B,C],[A,D]],[[A,D,C],[A,S]],X). 
B = S, 
D = S, 
X = [] ; 

потому что можно объединить B и D с S делать, что делать совпадение.

+0

Большое вам спасибо, я много об этом узнал. –

Смежные вопросы