Определить последний элемент первого списка, входящий также и во второй список и вывести его - Prolog
Формулировка задачи:
Люди добрые, прошу, помогите пожалуйста...
Даны два списка. Определить последний элемент первого списка, входящий также и во второй список и вывести его. Если совпадающих элементов нет, вывести «No».
Например: если дано "[2,3,4,5,6] [1,4,8,5]", ответом будет "5".
Решение задачи: «Определить последний элемент первого списка, входящий также и во второй список и вывести его»
textual
Листинг программы
domains
int=integer
intl=int*
predicates
app(intl,intl,intl)
rev(intl,intl)
memb(int,intl)
chk(intl,intl)
task(intl,intl)
clauses
app([],X,X).
app([H|T],X,[H|R]) :- app(T,X,R).
rev([],[]).
rev([H|T],R) :- rev(T,Q), app(Q,[H],R).
memb(_,[]) :- fail, !.
memb(H,[H|_]).
memb(H,[Q|R]) :- Q<>H , memb(H,R).
chk([],_) :- write("NO"),nl,!.
chk([H|_],Z) :- memb(H,Z), write(H),nl,!.
chk([H|R],Z) :- not(memb(H,Z)), chk(R,Z).
task(X,Y) :- rev(X,RX), chk(RX,Y).
Объяснение кода листинга программы
В коде используется язык программирования Prolog. Всего в коде 20 элементов, которые можно разделить на несколько групп:
- Домены:
- int=integer (целое число)
- intl=int* (список целых чисел)
- Предикаты:
- app(intl,intl,intl) (рекурсивная функция для работы со списками)
- rev(intl,intl) (рекурсивная функция для получения обратного списка)
- memb(int,intl) (предикат для проверки, является ли элемент списка уникальным)
- chk(intl,intl) (предикат для проверки, содержится ли элемент в списке)
- task(intl,intl) (предикат для решения задачи)
- Клаузы:
- app([],X,X). (базовый случай для функции app)
- app([H|T],X,[H|R]) :- app(T,X,R). (рекурсивный случай для функции app)
- rev([],[]). (базовый случай для функции rev)
- rev([H|T],R) :- rev(T,Q), app(Q,[H],R). (рекурсивный случай для функции rev)
- memb(_,[]) :- fail, !. (базовый случай для функции memb)
- memb(H,[H|_]). (рекурсивный случай для функции memb)
- memb(H,[Q|R]) :- Q<>H , memb(H,R). (рекурсивный случай для функции memb)
- chk([],_) :- write(
NO),nl,!. (базовый случай для функции chk) - chk([H|_],Z) :- memb(H,Z), write(H),nl,!. (рекурсивный случай для функции chk)
- chk([H|R],Z) :- not(memb(H,Z)), chk(R,Z). (рекурсивный случай для функции chk)
- task(X,Y) :- rev(X,RX), chk(RX,Y). (рекурсивный случай для функции task)
- Функции:
- app(intl,intl,intl) (рекурсивная функция для работы со списками)
- rev(intl,intl) (рекурсивная функция для получения обратного списка)
- memb(int,intl) (предикат для проверки, является ли элемент списка уникальным)
- chk(intl,intl) (предикат для проверки, содержится ли элемент в списке)
- task(intl,intl) (предикат для решения задачи)
- Последовательность выполнения:
- Сначала вызывается функция app, передавая в нее первый список, второй список и третий список.
- Затем вызывается функция rev, передавая в нее первый список и пустой список.
- После этого вызывается функция memb, передавая в нее элемент и первый список.
- Затем вызывается функция chk, передавая в нее первый список и второй список.
- Наконец, вызывается функция task, передавая в нее первый список и второй список.