Чтобы добавлять сообщения и комментарии, .

@qnikst:
qnikst

Вот есть задача составления расписания с ограничениями, это типичная задача для пролога, классы типов в haskell это prolog-like программирование. Вопрос можно ли решить задачу с составлением расписания чисто на уровне типов в haskell, и какие есть ограничения на задачу, которую можно решить?

@ndtimofeev:
ndtimofeev

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

@exception13:
exception13

не могу вкурить где тут косяк

:- [ais].

parseParameter(Atom, Term) :- read_term_from_atom(Atom, Term, [ ]).

parseParameters(Atoms, Terms) :- maplist(parseParameter, Atoms, Terms).

matchRules(Action, Result) :- rule(Action, Attributes), permutation(Attributes, Result).

server(Port) :-
http_server(http_dispatch, [ port(Port) ]).

aisReply(Request) :-
catch(http_parameters(Request, [ result(Result, [ list(atom) ] ) ]), _E, fail), !, format('Content-type: text/plain~n~n'), parseParameters(Result, Terms), matchRules(Action, Terms), write(Action).

из консоли все выполняется ок

?- parseParameters(['логин("M1234567890")', 'типОбращения(неисправность)', 'объектОбращения(интернет)'], Terms), matchRules(Action, Terms).
Terms = [логин([77, 49, 50, 51, 52, 53, 54|...]), типОбращения(неисправность), объектОбращения(интернет)],
Action = сбросСессии ;
false.

если же дергать через http то goal unexpectedly failed а если выкинуть &result=логин("M1234567890") то матчицо ок

@Kim:
Kim

Реализация redis клиента на чистом гнутом прологе github.com
Находится в зайчаточном состоянии, но может и в новом поколении вырастет маленькая армия прологокодеров?

@OCTAGRAM:
OCTAGRAM

Есть знатоки Пролога? Можно его переделать в препроцессор по типу m4?
stackoverflow.com

@omnivore:
omnivore

примитивное ооп для пролога pastebin.com

@Satana666:
Satana666

Жуйка, есть тут знающие пролог?

@omnivore:
omnivore

увидел комментарий jtootf'а habrahabr.ru надо же было такую глупость сморозить

@daapp:
daapp

Жуйк! А есть ли где в инете пример в виде исходников программы на прологе, которая работает с реальной базой знаний, в которой объекты имеют уникальные идентификаторы и много разных атрибутов, база может заполняться интерактивно пользователем. Мне принцип работы надо понять. Все учебники, что я видел, предлагают задачи, оторванные от реального мира.

@omnivore:
omnivore

создал jabber конференцию marginal@conference.jabber.ru. Для вопросов по "редким" темам: J, lisp, refal, prolog и fusion rock :) Присоединяйтесь!

@omnivore:
omnivore

решил проверить tuprolog — реализацию пролога на java. И в итоге я оказался разочарован скоростью его работы. Вот для сравнения за сколько отрабатывают разные пролог-машины на повторяемом 600 раз вычислении палиндрома списка из нескольких десятков элементов с помощью давнешнего рефал-модуля:

tuprolog — 15 секунд
swi prolog — 0.1 секунды
yap — 0.03 секунды

Один плюс у этого тупролога, что у него еще есть экспериментальный пакет для андроида. И хотя там указано, что он для версии >= 2.3.1, но все нормально запускается и на моем 2.2 Froyo.

@He4eT:
He4eT

Еще одна бессонная ночь. Бессмысленная и беспощадная. На этот раз с Прологом. Выяснилось, что он гораздо хуже Лиспа.Он вообще хуже всех походу. ЯП в котором нельзя программировать — говно и ненужен. Не до конца понимаю, зачем его преподают второму курсу математиков. Лучше бы Маткад какой-нибудь. И да, хватит на сегодня альтруизма

@omnivore:
omnivore

Продолжаем играться с прологом и рефалом. На этот раз добавим к нашей реализации рефаловского сопоставления по образцу жадные(greedy) переменные.

Напомню, что в языке Рефал есть такая интересная возможность, как паттерн-матчинг с так сказать "опережающим" поиском. (про Рефал писали, например, в недавнем номере ПФП). Т.о., предикат списка-палиндрома в рефале можно описать так:

Pal {
s.1 e.2 s.1 = <Pal e.2> ;
s.1 = True ;
= True;
e.1 = False ;
}

где e. переменные могут принимать любое значение подсписка (пустой, из одного или более элементов), а s. — один элемент списка.

Мы пытаемся построить с помощью пролога такой DSL, который позволил бы использовать рефаловское сопоставление по образцу (попутно добавив несколько других интересных плюшек :).

Пример предиката для определения, является ли список палиндромом, на нашем DSL приводился в одном из предыдущих постов. Сейчас же приведем несколько примеров работы с жадными переменными:

==
?- re([e(A), e(B)], [1,2,3]).
A = [],
B = [1, 2, 3].

?- re([e*(A), e(B)], [1,2,3]).
A = [1, 2, 3],
B = [].
==

Как видите, во втором примере "жадная" переменная A захватила максимально допустимое паттерном число элементов. Еще пример:

==
?- re([e(A), s(B), e(C)], [1,2,3]).
A = [],
B = s(1),
C = [2, 3].

?- re([e*(A), s(B), e(C)], [1,2,3]).
A = [1, 2],
B = 3,
C = [].
==

Добавим еще один тип переменных — непустые e-переменные. Назовем их "e+" переменные. Пример использования:
==
?- re([e+(A), e(B)], [1,2,3]).
A = [1],
B = [2, 3].

?- re([e*(A), e+(B)], [1,2,3]).
A = [1, 2],
B = [3].
==

И, в заключении, самый интересный, на мой взгляд, пример. Не забываем, что под капотом у нас пролог:
==
?- re([A,B], [1,2,3]).
A = s(1),
B = e([2, 3]).
==

В этом примере мы не указали тип переменных A и B, и пролог подставляет возможные значения типов переменных сам! Подставляет так, чтобы удовлетворить ограничению в две переменные. (замечу, что предлагается только 1 вариант, т.к. в реализации нашего DSL каждое правило оканчивается отсечением).

Вот такой вот получился наколеночный рефал :)

p.s. исходный код этой поделки на pastebin.com

@Kim:
Kim

В #1481938 я наврал. allocate/1 и deallocate/0 занимаются выделением активационных записей на отдельном стеке. Там хранятся только локальные переменные, которые понадобятся в коде предиката несколько раз. HEAP также организован в виде стека. HEAP, средствами WAM, очищается только на бэктрейсинге, когда удаляются все изменения сделанные в памяти после последней choice point.

@Kim:
Kim

В gprolog нет сборщика мусора. Для управления памятью в WAM используются инструкции allocate/1 и deallocate/0, что для меня достаточно неожиданно.

@nirthfurzahad:
nirthfurzahad

Большая проблема при работе с Prolog'ом для собственного бизнеса, в том, что вместо того что бы заниматься делом, и доделывать фичи – занимаешься лаконичностью кода, и вообще сокращением кол-ва строк.

@omnivore:
omnivore

свипрологовский xpce, как говорится, looks promising

@PineappleZombie:
PineappleZombie

А что благородные доны могут посоветовать почитать про Пролог? Ощущаю необходимость изучить этот язык.

@nobodyzzz:
nobodyzzz

Adventure in Prolog amzi.com

@omnivore:
omnivore

оказывается, что yap пролог много быстрее swi-prolog'а! пример из предыдущего поста работает на порядок быстрее с yap'ом

@omnivore:
omnivore

скачал 5й рефал, скомпилял и сравнил скорость вычисления палиндрома :) Рефал считает на порядок быстрее (в 10 с небольшим раз быстрее), чем моя прологовская реализация "рефаловского" сопоставления по образцу из предыдущего поста. Не так и плохо, я доволен :) Все-таки там ядро на си и идет компиляция в байткод.

@omnivore:
omnivore

попытаемся реализовать "рефаловское" сопоставление по образцу с помощью пролога. В рефале есть интересная возможность паттерн-матчинга с т.с. "опережающим" поиском. (про язык Рефал писали в недавнем номере ПФП).

Т.е. например предикат списка-палиндрома в рефале можно описать примерно так (синтаксис некоего условного рефал-языка взят по памяти):

pal( ).
pal(s.X).
pal(s.X e.Y s.X) :- pal(e.Y).

где e. переменные могут принимать любое значение подсписка (пустой, из одного или более элементов), а s. — один элемент списка. Такая интересная возможность, как мне кажется, могла бы быть востребована, например, во всякого рода трансляторах.

Но кроме как в рефале в явном виде такого механизма, как будто, и нет. Попытаемся реализовать такое поведение на прологе:

pref([], [X|Xs], [X|Xs]).
pref([X|Prefix], [X|List], Rest) :- pref(Prefix, List, Rest).

re([X | Pat], [X|Xs]) :- re(Pat, Xs), !.
re([e(X) | Pat], Xs) :- pref(X, Xs, Rest), re(Pat, Rest), !.
re([e(X)], X) :- !.
re([], []) :- !.

И теперь предикат списка-палиндрома на прологе можно записать так:

pal([]) :- !.
pal([X]) :- !.
pal(A) :- re([X, e(Y), X], A), pal(Y).

получился почти рефал :)

@omnivore:
omnivore

а вот хочется мне рефаловского паттерн-матчинга в прологе. посоветуйте какой инструмент лучше использовать? в идеале бы расширение синтаксиса для какого-нибудь swi-prolog'а

@nirthfurzahad:
nirthfurzahad

Для тех кому интересно одно из интересных применений Agent Oriented парадигмы, Prolog – ted.com . Я не совсем уверен кто это конкретно такой, но мой клиент работает с их отделом в MIT ^_^. Reverse Engineering of Brain. Хотя если честно, в основном пялимся в Excel.

@ulidtko:
ulidtko

Канонический constraint satisfaction на Прологе.
dpaste.org
Сынки, учитесь. Отцы, обсирайте.

@dk:
dk

Наткнулся на книгу «Logic, Programming and Prolog (2ed)» by Ulf Nilsson and Jan Maluszynski
Книга находится в свободном доступе. На первый взгляд весьма достойно написана.
ida.liu.se

@scame:
scame

Имеется ли в России сообщество prolog-программистов? Есть ли у них сайт или irc канал? Кто знает как в GNU prolog задаётся функция отрицания/1?

@nirthfurzahad:
nirthfurzahad

А можно ли рассматривать функторы, типа functor(atom1, atom2) из Prolog (если кто помнит) — Как Монады? Я все еще туплю с основами теории категорий.

@nirthfurzahad:
nirthfurzahad

Mercury в отличии от PROLOG может компилироватся в другие языки (C, C++, Java, Erlang), мне не нравится синтаксис, но это можно исправить макросами, главное, что бы на Cell работало шустро и не жрало оперативку.

@nirthfurzahad:
nirthfurzahad

Кстати Prolog оказывается используется для симуляции лабораторных животных, и животных в зоопарках. Фактически поведенческая модель животного описывается фактами и правилами в прологе, и потом корректируется, пока не добъемся похожих результатов между программой и реальным животным.

Очень хороший пример этого предоставлен в книге Тэйта про дельфина. В том примере, дельфина учили слову NOT ( то есть говоря ему touch not ball, дельфин должен был коснутся чего угодно кроме мячика ).

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

@nirthfurzahad:
nirthfurzahad

Чето все в мейлистах обсуждают цикличные consult запросы...а я даже не понимаю на фиг это надо

@nirthfurzahad:
nirthfurzahad

Для закрепления материала, буду писать о своих успехах и неудачах в прологе время от времени тут. Далее, используется SWI-Prolog ( 5.8.3 ). На случай, если я буду использовать термин AOP – это всегда означает Agent Oriented Programming, никаких Аспектов. <br/>
Одной из важных частей Prolog'а является KnowledgeBase. Базу можно фактами и правилами.<br/>
Факт ( Fact ) – это структура, содержащая в себе атомы, и другие факты.<br/>
Правило ( Rule ) — Это разноцидность функтора/эффектора. Если не работали с Декларативными языками, можно считать что это функция.<br/><br/>
Напишем файлик ( "specialists.p"):
person(joe, sap).
person(fred, sap).
person(peter, microsoft).
person(steve, microsoft).

collegues(X, Y) :- person(X, Z), person(Y, Z).

Первые четыре строчки, объявляют факты: Joe работает в SAP, Фрэд работает в САП, Питер и Стив работают в Майкрософте.

Последня строчка – правило. У нас есть два входящих параметра: X, Y. В теле Правила, мы описываем условие: нам нужно чтобы второе поле ( Z ) было одинаковым у обоих персон. Например если бы мы написали person(X, Z), person(Y, A).

Откомпилируем KnowledgeBase:
?- ['specialists.p'].
% specialists.p compiled 0.00 sec, 208 bytes
true.

?- collegues(joe, fred).
true.

?- collegues(joe, steve).
false.

@nirthfurzahad:
nirthfurzahad

likes(wallace, cheese).
likes(grommit, cheese).
likes(wendolene, sheep).

friends(X, X) :- !, fail.
friends(X, Y) :- likes(X, Z), likes(Y, Z).

?- likes(wallace, sheep).
false.

?- likes(grommit, cheese).
true.

?- friends(wallace, wallace).
false.

?- friends(grommit, wallace).
true.


Пролог рулит ^_^

@fixpoint:
fixpoint

Год назад видел в рассылке haskell-cafe такую задачу: есть два списка, ns :: [Int] и xs :: [T]. Нужно разбить список xs на подсписки длинами из ns. Т.е. takeList [2,1,3] "omgwtf" = ["om", "g", "wtf"]. К этой задаче приводили несколько решений разных уровней навороченности. Потом я линк на все это дело потерял, и вот наконец-то опять нашел. "Новичковское" решение выглядит так:

takeList [] _ = []
takeList _ [] = []
takeList (n : ns) xs = head : takeList ns tail
where (head, tail) = splitAt n xs

А самое продвинутое — вот так:

takeList = evalState . map (State . splitAt)

А на прологе (отсюда: kerneltrap.org ) — оказывается, можно даже вот так (устанавливается зависимость между исходным списком Xs, списком длин Ls и результатом — списком подсписков — Ps):

takeList(Xs,Ls,Ps) :- maplist(length,Ps,Ls), flatten(Ps,Xs).

@Konst:
Konst

Млин, я потратил довольно много времени, прежде чем понял, что мои предикаты работают, просто при вычислении надо давать интерпретатору на каждом шагу команду ";" для дизъюнкции, а не точку, он тогда завершает просмотр.

@lig:
lig

Жуйк, а ты знаешь Prolog?

@lig:
lig

таки подружил eclipse и prolog с помощью вот этого: roots.iai.uni-bonn.de

@Un1oR:
Un1oR

Чем мне нравятся лабы по ИИ, там это отчётами на 3 листика, включая титульник =))

@CA:
CA

2 лабы по Прологу и Лиспу + 6 листов юридической терминологии. Сочни, вкусни.