
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.3] |
![]() |
|
Сообщ.
#1
,
|
|
|
Всем привет, вот играюсь со списками в прологе
И вот решил спросить почему у меня не получается, того что я ожидаю от пролога ![]() ![]() has(X,[_|Y]) :- has(X,Y). % если элемент хвоста равен искомому элементу значение будет «истина» Допустим мы берём элемент и список. В конечном результате у нас false ![]() ![]() ?- has(2,[1,2,3]). |
Сообщ.
#2
,
|
|
|
не хватает граничного условия рекурсии.
% искомый элемент совпал с головой списка has(H,[H|_]). %искомый элемент содержится в хвосте списка has(X,[_|T]):- has(X,T). |
Сообщ.
#3
,
|
|
|
Цитата Swetlana @ не хватает граничного условия рекурсии. % искомый элемент совпал с головой списка has(H,[H|_]). %искомый элемент содержится в хвосте списка has(X,[_|T]):- has(X,T). Вы Светлана как всегда на высоте, а я вот хочу понять списки и написать програмки. ну пока что туго выходит ![]() Добавлено Суть такова проверить лист, все ли цифры у нас стоят по порядку. Т.е как я понимаю. Берём лист, отсекаем Head, Tail дальше сравниваем Head < Tail, дальше с отсатка Tail дальше делим Head, Tail и так проверяем пока нету в списке Head > Tail и как только первый находим делаем отсечение ! и пишем faise |
Сообщ.
#4
,
|
|
|
Может, вот это поможет?
Прикреплённый файл ![]() |
Сообщ.
#5
,
|
|
|
мда чего-то не распечатывает линукс файлы с русским именем, сейчас попробую через терминал
Добавлено Всё распаковал иду читать спасибо |
Сообщ.
#6
,
|
|
|
Цитата Суть такова проверить лист, все ли цифры у нас стоят по порядку. %в пустом списке всё в порядке check([]). %в одноэлементном тоже check([X]). % рекурсивное правило для списка хотя бы из двух элементов check([X,Y|T]):- X<=Y, check(T). |
Сообщ.
#7
,
|
|
|
мда задачки простые а я вот читаю, по кускам со всех сайтов и пока не понял.
иду почитаю и постараюсь вникнуть ![]() |
Сообщ.
#8
,
|
|
|
Идея простая. Если в списке выделяем голову, то имеем граничное условие для пустого списка и рекурсивное правило для непустого. Обрабатываем первый элемент, для хвоста вызываем рекурсию.
В вашей задаче нужно было выделить два первых элемента [X,Y|T], поэтому получилось два граничных условия - одно для обработки пустого списка, второе - для одноэлементного. |
Сообщ.
#9
,
|
|
|
Хмм почему вы не преподаёте у нас в Литве
![]() ![]() |
Сообщ.
#10
,
|
|
|
у меня проблема, в первом списке повторы могут быть
![]() ![]() ![]() member(X, [X|_]):-!. member(X, [_|Y]):- member(X, Y). general([], _, []). general([X|T], L2, [X|Z]):- member(X, L2), !, general(T, L2, Z). general([_|T], L4, L2):- general(T, L4, L2). Как это можно было бы локализовать ![]() ![]() |
Сообщ.
#11
,
|
|
|
Что локализовать? В чём заключается задание?
|
Сообщ.
#12
,
|
|
|
Например ?-general([a,b,c,d][b,d,e],R) вернёт R=[b,d]. Тут всё ок, а вот если в первый список добавить ещё повтор например две bb то они и будут две в списке, хоть повтора второго в спискк не будет
Добавлено И вот этот пример не понятен find([a,c,a,b,b,b,b,a,g], 4, C). Получаем что C=b. Т.е идём рекурсивно. По два элемента провнряем если истина +1 как не мовпадает считаем кол-во и если >= 4 тогда добавляем в C else обнуляем counter и считаем дальше? Прааильно я понимаю? |
Сообщ.
#13
,
|
|
|
Цитата xpoint @ Например ?-general([a,b,c,d][b,d,e],R) вернёт R=[b,d]. Тут всё ок, а вот если в первый список добавить ещё повтор например две bb то они и будут две в списке, хоть повтора второго в спискк не будет Процедура del2 удаляет из списка все повторы, то есть каждый элемент в возвращаемый список входит ровно один раз. Поэтому после general вызывайте del2 general([a,b,b,c,d][b,d,e],R), del2(R,R1). ![]() ![]() %из пустого списка повторы уже удалены del2([],[]). %если голова списка принадлежит хвосту, то отбрасываем её del2([H|T],T1):- member(H,T),!, del2(T,T1). %если голова списка не принадлежит хвосту, делаем ей головой целевого списка del2([H|T],[H|T1]):- del2(T,T1). member(H,[H|T]):-!. member(X,[_|T]):- member(X,T). Добавлено Цитата xpoint @ И вот этот пример не понятен find([a,c,a,b,b,b,b,a,g], 4, C). Получаем что C=b. Т.е идём рекурсивно. По два элемента провнряем если истина +1 как не мовпадает считаем кол-во и если >= 4 тогда добавляем в C else обнуляем counter и считаем дальше? Прааильно я понимаю? Я тоже не понимаю. Напишите процедуру find тогда объясню, что она делает. |
Сообщ.
#14
,
|
|
|
По сути дела если использовпть предикат del2 задание будет совмем не верно выполенно "список R состпвлен из общих элементов двкх списков"
А вот что спрашивал в списке S есть K последовательно идущих одинаковых эллементов, которые записывает например в E |
Сообщ.
#15
,
|
|
|
xpoint, наконец, увидела задания
![]() Вечером отвечу, сейчас нет времени. |
Сообщ.
#16
,
|
|
|
Цитата Swetlana @ ок, подождём я как всегда не успеваю ..... Сегодня ещё пойду уточню, может я не так понимаю эти два задания и не так говорю вот что у меня получилось ![]() ![]() member(X, [X|_]):-!. member(X, [_|Y]):- member(X, Y). %из пустого списка повторы уже удалены del2([],[]). %если голова списка принадлежит хвосту, то отбрасываем её del2([H|T],T1):- member(H,T),!, del2(T,T1). %если голова списка не принадлежит хвосту, делаем ей головой целевого списка del2([H|T],[H|T1]):- del2(T,T1). general([], _, []). general([X|T], L2, [X|Z]):- member(X, L2), !, general(T, L2, Z). general([_|T], L4, L2):- general(T, L4, L2), del2(L2, L3), L2=L3. Результат ![]() ![]() ?- general([a,b,c,d], [b,d,e], R). R = [b, d]. ?- general([a,a,b,c,d], [b,d,e], R). R = [b, d]. ?- general([a,a,b,c,d], [a,b,d,e], R). R = [a, a, b, d]. ?- general([a,a,b,c,d], [b,a,d,e], R). R = [a, a, b, d]. Например последний, первый список имеет два a, а во втором только одна, т.е ответ у нас два a. Это не решает проблему |
Сообщ.
#17
,
|
|
|
Цитата xpoint @ в списке S есть K последовательно идущих одинаковых эллементов, которые записывает например в E ![]() ![]() kart([], K, E). kart([_], K, E). kart([X,Y|T], K, E):- X=Y, kart(T, K, E). kart([_|T], K, E):- kart(T, K, E). перебираем, а вот как в них определить K элементов по очереди и записать в E |
Сообщ.
#18
,
|
|
|
процедура cross возвращает пересечение двух списков,
для тестового примера [2,5,2,5] ![]() ![]() domains list = integer* predicates del(integer,list,list) member(integer,list) cross(list,list,list) goal cross([2,5,2,5,2,5],[2,2,3,5,5],L), write(L). clauses cross([],_,[]):-!. % голова первого списка принадлежит второму списку cross([H|T],L,[H|T1]):- member(H,L),!, del(H,L,L1),% удаляем элемент из второго списка cross(T,L1,T1). % голова первого списка не принадлежит второму списку cross([H|T],L,T1):- del(H,L,L1), cross(T,L1,T1). del(_,[],[]):-!. del(H,[H|T],T):-!. del(X,[H|T],[H|T1]):- del(X,T,T1). member(H,[H|T]):-!. member(X,[_|T]):- member(X,T). |
Сообщ.
#19
,
|
|
|
Элемент списка, который идёт подряд ровно K раз
В тестовом примере это 5. ![]() ![]() domains list = integer* predicates find(list,integer,integer) count(integer,list,integer) goal find([2,2,5,5,5,2],3,X), write(X). clauses %в пустом списке любой элемент идёт 0 раз count(_,[],0):-!. %заданный элемент не совпадает с головой списка, значит, идёт 0 раз count(X,[H|T],0):- X<>H,!. %заданный элемент совпадает с головой списка count(H,[H|T],K):- count(H,T,M), K=M+1. find([H|T],K,H):- count(H,[H|T],K),!. find([_|T],K,Y):- find(T,K,Y). |
Сообщ.
#20
,
|
|
|
Спасибо вам Света, мда совсем не так думаю, как надо. Вот и проблемы
![]() |
Сообщ.
#21
,
|
|
|
Потому что хотите в одном правиле сделать сразу и всё. А на Прологе так не пишут. Сделали чуть-чуть, а для всего остального вызываем вспомогательную процедуру.
Например. Надо найти элемент, который в списке идёт K раз подряд. Элементов много. Поэтому проверим вначале для первого, будет ли он K раз повторяться. Как это проверить внутри правила? А внутри правила не надо ничего проверять, надо вызвать вспомогательную процедуру count, она и проверит. ![]() ![]() find([H|T],K,H):- count(H,[H|T],K),!. Если первый элемент списка не повторяется K раз, то удалим его. А для уменьшенного списка уже можно вызвать рекурсию. ![]() ![]() find([_|T],K,Y):- find(T,K,Y). |
Сообщ.
#22
,
|
|
|
Вот вопрос на засыпку в одном файле может быть несколько задач, если например member уже был определён до этого и второй раз пытаешся определить
![]() Добавлено Цитата Swetlana @ Потому что хотите в одном правиле сделать сразу и всё. А на Прологе так не пишут. Сделали чуть-чуть, а для всего остального вызываем вспомогательную процедуру. Например. Надо найти элемент, который в списке идёт K раз подряд. Элементов много. Поэтому проверим вначале для первого, будет ли он K раз повторяться. Как это проверить внутри правила? А внутри правила не надо ничего проверять, надо вызвать вспомогательную процедуру count, она и проверит. ![]() ![]() find([H|T],K,H):- count(H,[H|T],K),!. Если первый элемент списка не повторяется K раз, то удалим его. А для уменьшенного списка уже можно вызвать рекурсию. ![]() ![]() find([_|T],K,Y):- find(T,K,Y). Да да я привык что в c++ или на каком pascal всё сразу, а теперь вот пролог нужно изучать, и получается что я хочу от него всё сразу и без проблем Добавлено Хмм а вот этот пример что мы смотрели ![]() ![]() did([]). did([_]). did([X,Y|T]):- X =< Y, did(T). [/code] Как я понял проверяет например ![]() ![]() ?- did([4,18,2,100]). 4=<18 2=<100 И получаем true По сути дела тут false, так как тут 18 не меньше чем 2 ![]() Добавлено Иду подумаю, мне кажется тут что-то не трудное ![]() |
Сообщ.
#23
,
|
|
|
Цитата Вот вопрос на засыпку в одном файле может быть несколько задач, если например member уже был определён до этого и второй раз пытаешся определить ![]() Иногда 2 разных мембера нужно описывать. member может быть детерминированный, с отсечением, который находит только первое вхождение элемента. Может быть недетерминированный без отсечения, при возвратах будет поочерёдно все вхождения находить. Если для одной задачи нужен member детерминированный, а для другой недетерминированный, то описывать два раза, назвать member и member1. Добавлено Цитата Хмм а вот этот пример что мы смотрели Здесь ошибка, сори. Надо так did([X,Y|T]):- X =< Y, did([Y|T]). |