Пролог: сравните три списка, 1-й элемент списка 1 с последним элементом списка 2 И второй с последним элементом списка 3 - PullRequest
0 голосов
/ 01 июля 2019

Напишите программу PROLOG (т.е. набор предикатов), которая реализует следующую функцию. Программа должна сравнить три списка и определить, совпадает ли первый элемент первого списка с последним элементом второго списка и со второго по последний элемент третьего списка. Вызовите основной предикат: сравнить (List1, List2, List3).

Я пошел дальше и написал отдельные коды для двух отдельных условий, которые работают сами по себе. 1. 1-й элемент списка List1 равен последнему элементу списка List2 2. 1-й элемент Списка1 равен второму последнему элементу Списка3.

Теперь у меня проблемы с объединением кодов для совместной работы. Мой ход мыслей заключается в том, что условие 1 и условие 2 должны выполняться отдельно, прежде чем будет выполнено общее условие. Так что как-то я должен запустить код для условия 1 и условия 2 самостоятельно, но в той же программе? И если оба из них вернут истину, тогда у меня может быть что-то еще, что говорит, что мои условия выполнены.

compare(List1,List2,List3):- last(true), secondLast(true).

Condition1:

last([HeadList1|RestList1],[HeadList1]).
last([HeadList1|RestList1],[HeadList2|RestList2]) :-
  last([HeadList1|RestList1],RestList2).

Condition2:

secondLast([HeadList1|RestList1],[HeadList1,RestList3]).
secondLast([HeadList1|RestList1],[HeadList3|RestList3]) :-
  secondLast([HeadList1|RestList1],RestList3).

Что я ожидаю:

?- compare([2,8,9,1],[4,5,6,2],[1,2,3]).
yes

?- compare([a,b,c,d,k],[a,c,f,e],[a,s]).
no

Ответы [ 2 ]

1 голос
/ 02 июля 2019

@ damianodamiano предлагает реализацию, использующую reverse/2, и я подумал, что было бы интересно посмотреть, что это такое.

mycompare([H|_], L2, L3) :-
    reverse(L2, [H|_]),
    reverse(L3, [_, H|_]).

reverse/2 несколько дороже, чем обход списка, так что это не можетбыть лучшим способом решения проблемы, я думаю, что стоит посмотреть, потому что он довольно близок к заявленному вопросу и демонстрирует, что эта проблема действительно решается путем объединения и только объединения.Решение damianodamiano имеет аналогичное свойство: вы находите первое, H, а затем показывает, что H появляется в других позициях в двух других списках.

Теперь у меня есть несколько разных отзывов для вас:

  • Вы правы, полагая, что если у вас есть два предиката, скажем p1 и p2, вы можете объединить их, выполнив p1, p2.В общем, они собираются делиться привязками переменных между ними, потому что то, что вы делаете в программировании на Прологе, это установка отношений между некоторыми вещами .

    Именно поэтому синглтоновые «предупреждения» на самом деле являются ошибками: они показывают случаи, когда вы полагаете, что есть связь, но когда Пролог мог сказать, что вы нигде не указывали переменную, поэтому связь не была установлена.

  • Ваши имена переменных действительно плохие.Если 99% всех ваших имен переменных совпадают, вы запутаетесь.Было бы лучше использовать A и B, чем HeadList1 и HeadList2.Если вы должны использовать такие имена, упростите до H1 и H2.Когда вы видите [X|Y], вы знаете, что X - это заголовок списка, а Y - это хвост списка, вам не нужно делать эту информацию частью имени.Сфокусируйтесь на содержимом переменной, если можете, или на связи, которую вы пытаетесь установить между выражениями, частью которых является переменная.

  • Предикаты Prolog делают not «Верни истину».Они могут быть успешными или неудачными, но они не оцениваются как функции: вы не можете заменить mycompare(A,B,C) на true только потому, что mycompare(A,B,C) успешен, вы не можете присвоить значение результату R = mycompare(A,B,C), и вы не можете вложить предикаты, такие как writeln(mycompare(A,B,C)).Так что избавьтесь от этой привычки сейчас, чтобы не запутаться в будущем.

1 голос
/ 01 июля 2019

С SWI вы можете использовать last/2 и определение secondTast/2 из этого вопроса :

secondLast([X,_], X).
secondLast([_|T], X) :- secondLast(T, X).

my_compare([H|_],L1,L2):-
    last(L1,H),
    secondLast(L2,H).

?- my_compare([2,8,9,1],[4,5,6,2],[1,2,3]).
true

?- my_compare([a,b,c,d,k],[a,c,f,e],[a,s]).
false 

Вы можете поставить сокращение, чтобы избежать ложного решения в первом запросе. Это первое решение, вы можете получить супер фантазию и использовать, например, reverse/2 и другие предикаты, чтобы найти другое решение (но, возможно, медленнее).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...