Пролог - сравнить 2 списка, которые содержат другие списки в качестве элементов

Я новичок в PROLOG, и я нахожу его довольно сложным. Мне нужно вернуть T/F, если 2 списка имеют одинаковые элементы (они равны), независимо от их положения в списках. Пока я могу легко сравнить два списка, если их элементы состоят из символов, строк или чисел. Но я не могу понять, как сравнивать списки, содержащие числа и списки чисел ИЛИ символы и списки символов.

Например:

?- compare([[15,7,5],9,4],[4,[5,15,7],9])
true.

Но:

?- compare([22,[100,36],1],[[36,100],[22,1]])
false.
?- compare([22,[100,36],1],[[[36,100]],22,1])
false.
?- compare([22,100,36,1],[[36,100,22,1]])
false.

Любые идеи, как я могу реализовать такую ​​программу?

Спасибо

Пролог не возвращает true или false. На самом деле он ничего не возвращает. Программа либо преуспевает, либо терпит неудачу. Если это удастся, вы можете проверить переменные в своем запросе и увидеть их значения.

Enigmativity 14.12.2020 00:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
120
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вот мой подход, вы можете использовать flatten.

1. Сначала используйте is_list, чтобы найти весь внутренний список, затем сравните внутренние списки, используя предикат innerListCheck. flatten просто берет все внутренние списки и объединяет их в один список. сгладьте оба списка, затем убедитесь, что оба списка имеют одинаковую длину. После этого используйте предикат checkmember.

2. Предикат checkmember сверяет элементы первого списка со вторым списком. если все элементы первого списка существуют во втором, то они одинаковы.

compare(List1,List2):-
list(List1,A1),
list(List2,A2),
innerListCheck(A1,A2),
flatten(List1,[W1|R1]),
flatten(List2,Res2),
length([W1|R1],Len1),
length(Res2,Len2),
Len1=Len2,
checkmember([W1|R1],Res2).

checkmember([],_).
checkmember([H|T],List2):-
    ( member(H,List2)->
    checkmember(T,List2)).
    
innerListCheck([],[]).
innerListCheck([H|T],[H2|T2]):-
    check2(H,H2),
    innerListCheck(T,T2).

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

list([],[]).
list([H|T],[H|B]):-
    is_list(H),
    list(T,B).
list([H|T],B):-
    \+is_list(H),
    list(T,B).

Пример:-

?-compare([22,[100,36],1],[[36,100],[22,1],[9]]).
false
?-compare([22,100,36,1],[[36,100,22,1]])
false
?-compare([22,[100,36],1],[[[36,100]],22,1])
false
?-compare([22,100,36,1],[[36,100,22,1]])
false
?-compare([[15,7,5],9,4],[4,[5,15,7],9])
true
false

Спасибо за быстрый ответ. сравнить([22,[100,36],1],[[36,100],[22,1]]). хотя должно быть ложным. Идея заключается в том, что если 2 списка содержат подсписки, которые содержат одни и те же элементы, независимо от их положения, то вывод должен быть истинным. Так что мне нужно, чтобы 2 списка содержали не только одни и те же элементы, но и одни и те же подсписки. Как пример, который я привел. Спасибо

user14819924 13.12.2020 23:14

Это должно быть правдой, первый список после сглаживания становится: [22,100,36,1], а второй [36,100,22,1]. Следовательно, при сравнении должно быть правдой.

Reema Q Khan 13.12.2020 23:18

@user14819924 user14819924 хорошо, это другая концепция. Дайте-ка подумать.

Reema Q Khan 13.12.2020 23:20
Ответ принят как подходящий
list([]) :- !.
list([_|_]) :- !.

reccheck([],[]).
reccheck([H|T],[HH|TT]):-
    recSort(H,HH),
    reccheck(T,TT).

recSort(L,L):-
    \+ list(L).
recSort(In,Out):-
    list(In),
    reccheck(In,SubSortL),
    sort(SubSortL,Out).

compare(L1,L2):-
    recSort(L1,LL),
    recSort(L2,LL).

?- compare([[15,7,5],9,4],[4,[5,15,7],9]).
true ;
false.

?- compare([22,[100,36],1],[[36,100],[22,1]]).
false.

?- compare([22,[100,36],1],[[[36,100]],22,1]).
false.

?- compare([22,100,36,1],[[36,100,22,1]]).
false.

Поэтому мое решение рекурсивно сортирует любые подсписки и сравнивает, совпадают ли два отсортированных списка. Для рекурсивной сортировки нужны два предиката. Тот, который сортирует (рекурсивные) списки (recSort/2), и тот, который проходит по спискам и применяет сортировку recSort ко всем элементам списка (reccheck/2).

Просто более краткая реализация предиката рекурсивной сортировки с использованием maplist/3:

rsort(A, B) :-
    (  is_list(A)
    -> sort(A, S),           % sort input list
       maplist(rsort, S, B)  % recursively sort each element of the sorted input list
    ;  A = B  ).

compare(A, B) :-
    rsort(A, S),
    rsort(B, S).

Другие вопросы по теме