Специалист
Сообщений: 8,170
Сказал(а) спасибо: 5
Поблагодарили 339 раз(а) в 338 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
|

13.01.2012, 01:05
Режимы детерминизма фактов:
determ - факт может быть в одном экземпляре или не быть вовсе.
nondeterm - (режим по умолчанию) фактов может быть сколько угодно, даже ни одного.
single - факт только один. Как правило используется для счётчиков, при объявлении счётчику присваивается начальное значение. single-факты или ещё их называют факты-переменные допускают разрушающее присваивание и играют роль переменных с "глобальной" областью видимости из настоящих императивных языков. Используя их можно максимально ускорить прогу при подсчётах чего-либо. Тип факта-переменной может быть не только число, строка, символ и т.п., но и список например.
Вот пример подсчёта числа недетерминированных фактов хрень() в БД с помощью single-факта, который играет роль счётчика.
Visual Prolog Код:
implement main open core, console
constants className = "main". classVersion = "$JustDate: $$Revision: $".
class facts хрень: (integer) nondeterm. i : unsigned := 0. % факт-пееменная обязательно инициируется при объявлении
class predicates сколько_хрени: (unsigned) procedure (o).
clauses classInfo(className, classVersion). хрень(567). хрень(-34). хрень(5). хрень(90).
сколько_хрени(_) :- хрень(_), i:=i+1, fail. сколько_хрени(i).
clauses run():-init(), сколько_хрени(N), write(N), _=readline(). end implement main
goal mainExe::run(main::run).
Прога нарисует конечно 4.
Режимы детерминизма предикатов зависят от потока параметров.
Вот хороший пример из библиотеки, доставшейся семёрке по наследству от пятёрки. Предикат конкатенации строк:
Visual Prolog Код:
concat : (string String1,string String2,string LongString) procedure (i,i,o) determ (o,i,i), (i,o,i), (i,i,i).
Пояснения:
procedure (i,i,o) - если две соединяемых строки заданы, то результат (третий аргумент) будет единственным.
determ (o,i,i), (i,o,i) - если задана одна из коротких строк и длинная строка , то здесь два варианта: 1) короткая строка - есть часть длинной строки и это успешное единственное решение, 2) короткая строка не является частью длинной строки, неуспех, откат назад.
determ (i,i,i) - все аргументы заданы, если короткие строки при склеивании дают третий аргумент (длинную строку), то успех, иначе - неуспех и откат назад.
Если предикат используется с несколькими потоками параметров, то все эти потоки надо указывать. Например классический предикат определения элемента списка может иметь первый параметр как входной, так и выходной:
Visual Prolog Код:
implement main open core, console
constants className = "main". classVersion = "$JustDate: $$Revision: $".
class predicates member:(integer,integer*) nondeterm (i,i) (o,i).
clauses classInfo(className, classVersion).
clauses member(A,[A|_]). member(A,[_|B]):- member(A,B).
clauses run():-init(), if member(3,[1,2,3,4,5]),! then write("3 - элемент списка"),nl end if, (member(3,[1,2,3,4,5]),write("3 - элемент списка"),nl,!;succeed), % логический аналог if-then-else nl, foreach member(A,[1,2,3,4,5]) do write(A," - элемент списка ") end foreach, nl, (member(A,[1,2,3,4,5]),write(A," - элемент списка "),fail;succeed), % логический аналог foreach _=readline(). end implement main
goal mainExe::run(main::run).
А вот это классика жанра - предикат append - соединение двух списков в третий. Четыре режима детерминизма в одном предикате! Его аргументами можно крутить практически как угодно (обратите внимание на полиморфные списки в этом предикате):
Visual Prolog Код:
implement main open core, console
constants className = "main". classVersion = "$JustDate: $$Revision: $".
class predicates append:(Z*,Z*,Z*) nondeterm (i,i,i) (o,i,i) determ (i,o,i) multi (o,o,i) procedure (i,i,o).
clauses classInfo(className, classVersion).
clauses append([],L,L). append([A|L1],L2,[A|L]):- append(L1,L2,L).
clauses run():-init(), append([1,2],[3,4,5],L), write(L),nl,nl, % procedure (i,i,o) (append(L1,[3,4,5],[1,2,3,4,5]), write(L1),nl,!; write("L1 не найден"),nl), %nondeterm (o,i,i) (append(L11,[3,4],[1,5]), write(L11),nl,!; write("L11 не найден"),nl),nl, %nondeterm (o,i,i) (append([1,2,3],L2,[1,2,3,4,5]), write(L2),nl,!; write("L2 не найден"),nl), %determ (i,o,i) (append([9],L22,[4,5]), write(L22),nl,!; write("L22 не найден"),nl),nl, %determ (i,o,i) (append([1,2,3],[4,5],[1,2,3,4,5]), write(":)"),nl,!; write(":("),nl), %nondeterm (i,i,i) (append([1,0],[5],[9,8,4,5]), write(":)"),nl,!; write(":("),nl),nl, %nondeterm (i,i,i) (append(X,Y,[1,2,3,4,5]), write(X," ",Y),nl,fail; succeed), %multi (o,o,i) _=readline(). end implement main
goal mainExe::run(main::run).
Результат:
Цитата:
[1,2,3,4,5]
[1,2]
L11 не найден
[4,5]
L22 не найден
: )
:(
[] [1,2,3,4,5]
[1] [2,3,4,5]
[1,2] [3,4,5]
[1,2,3] [4,5]
[1,2,3,4] [5]
[1,2,3,4,5] []
|
Обратите внимание непроложисты, что в последнем случае длинный список разбивается на все возможные комбинации двух списков.
Чтобы такое повторить в императивном языке пришлось бы наверное писать шесть различных процедур - каждую для своего потока параметров.
p.s. aag, вчера наконец-то я доел холодец  10 литров холодца это всё же перебор.
Последний раз редактировалось Винитарх; 13.01.2012 в 01:12
|
|
|
Специалист
Сообщений: 8,170
Сказал(а) спасибо: 5
Поблагодарили 339 раз(а) в 338 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
|

14.01.2012, 00:16
Обработка строк.
Строки внутри Пролога представляются нуль-терминальным массивом двухбайтовых символов (unicode-16). Конечно Пролог может их конвертировать в ANSI-строки и обратно.
Языковые средства VIP унифицируют строки (знак =) и проверяют на > < в соответствии с кодами символов. Это одинаково во всех языках. Операции со строками описаны в нескольких классах, основной из которых класс string. В нём больше 80 предикатов для обработки строк. Кроме него есть string8, codePageID, RegExp (регулярные выражения), криптография_для_строк (чуток), templateExpander (чуток). Ну ещё есть класс красно-чёрных деревьев, всяческие коллекции. Они работают со строками, хотя с чем они только не работают.
Описание классов можно найти в хэлпе: Help -> Visual Prolog help -> Содержание -> string
Вот показательные примеры (названия предикатов говорят сами за себя):
Visual Prolog Код:
implement main open core, console
constants className = "main". classVersion = "$JustDate: $$Revision: $".
class predicates scan: (string, string*) procedure (i,o).
clauses classInfo(className, classVersion).
scan(S,[T|L]) :- string::frontToken(S,T,R), !,scan(R,L). scan(_,[]).
clauses run():-init(), L = string::toCharList("Питон Пролог !"), SortedL = list::sort(L), S = string::createFromCharList(SortedL), write(S),nl, scan("Выражение: 3.14e+5 * ln(0x0A1E) ",Результат), write(Результат),nl, Ф = "Тарам-парам", writef("Хэш-функция( % ) = %",Ф,string::hash(Ф)), _=readline(). end implement main
goal mainExe::run(main::run).
Результат:
Цитата:
!ППгилнооорт
["Выражение",":","3.14e+5","*","ln","(","0x0A1E",") "]
Хэш-функция( Тарам-парам ) = 183776961
|
Разбор полётов:
" !ППгилнооорт" - это отсортированный список символов исходной строки "Питон Пролог !". Правда сортировка выполнялась предикатом из класса List, так как "своих" средств сортировки в классе string нет.
["Выражение",":","3.14e+5","*","ln","(","0x0A1E",") "] - это список лексем строки "Выражение: 3.14e+5 * ln(0x0A1E) ". Обратите внимание на корректный разбор вещественных чисел в формате мантисса-порядок, недесятичных чисел и т.п. Весь разбор делается простейшим предикатом scan, описанным в этой же программе. Здесь главную роль играет предикат fronttoken, который корректно отрывает лексемы от строки по достаточно богатому набору правил. Такого предиката я не видел в других языках, имхо.
Хэш-функция( Тарам-парам ) = 183776961 - это хэш-функция заданной строки. Следует заметить, что в классе cryptography есть развитые функции для обработки строк.
Для ввода-вывода строк есть классы file и stream. Работать с ними также как и в других языках. То есть можно прочитать файл целиком в память, или дёргать порциями, хоть посимвольно. Запись - также.
|
|
|
Специалист
Сообщений: 8,170
Сказал(а) спасибо: 5
Поблагодарили 339 раз(а) в 338 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
|

05.02.2012, 17:08
Списки.
В Прологе по большому счёту есть три способа представления данных: термы (нерекурсивные структуры, списки, деревья), бинарные данные и факты. С помощью бинарных данных можно организовывать массивы, но главное их назначение - безопасное хранение и передача данных. Бинарные данные и термы обрабатываются только в рекурсивных циклах, а факты хороши для циклов с откатом. Всё. Другого не дано!
Особо въедливые могут сказать, что бинарные данные это те же термы. Я отвечу - да. Списки в Прологе односвязные. С их помощью организуются очереди (есть класс queue).
В VIP есть класс для работы со списками, он так и называтся list и содержит 70 предикатов. Класс этот примечателен тем, что половина его предикатов полиморфны. Другая половина - нет. Это потому, что в некоторых списковых задачах надо учитывать тип элементов, например, при сортировке надо сравнивать элементы на =, < или >. И если числа, символы, структуры, двоичные данные и строки, как элементы списка, сравниваются без проблем, то пользователем определённые структуры надо доопределять относительно операций сравнения. Для этого используются предикатные домены и функциональные домены.
Класс list и примечателен тем, что в нём вовсю используются предикатные и функциональные домены. Примерно как в Хаскеле, в котором есть развитая система определения типов.
Ладно, хватит щёлкать клювом. Переходим к простым и осязаемым примерам.
Вначале самые простые предикаты, которым по барабану тип элементов списка, ну т.е. к полиморфным:
Visual Prolog Код:
implement main open core, console, list constants className = "main". classVersion = "$JustDate: $$Revision: $". class predicates clauses classInfo(className, classVersion).
run():-init(), L=[1,2], L1=[3,4,5], write(append(L,L1)),nl, % соединение двух списков write(append(L,L,L,L1,L1)),nl, % соединение пяти списков write(appendList([L,L1,L,L1,L,L1])),nl, % соединение списка списков L2=[1,2,3,4,5,6,7,8,9], write(difference(L,L2)),nl, % разность множеств(списков): L\L1 write(intersection(L,L2)),nl, % пересечение двух множеств(списков) write(drop(3,L2)),nl, % отрезаем первые три элемента и возвращаем остаток foreach E=getMember_nd(L2) do write(E," -> ") end foreach,nl, if isMember(1,L1) then write("принадлежит") else write("не принадлежит") end if,nl, _=readline().
end implement main
goal mainExe::run(main::run).
Результаты:
Цитата:
[1,2,3,4,5]
[1,2,1,2,1,2,3,4,5,3,4,5]
[1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
[]
[1,2]
[4,5,6,7,8,9]
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 ->
не принадлежит
|
Остальные предикаты (из разряда самых простых) мне запускать влом. Вот совсем некоторые из них (в хэлпе к классу list все они описаны):
Цитата:
length(L)
maximum(L)
minimum(L)
nth(Index,L) - n-й элемент списка
reverse(L)
setNth(Index,L,NewItem) - замена n-го элемента новым
sort(L,Order)
split(Index,L,LeftList,RightList) - расщепление списка на два в заданной позиции
take(Count,List) - префикс списка из Count элементов (противоположен предикату drop)
union(L,L1) - объединение двух множеств(списков)
|
Теперь zip и unzip. Они тоже полиморфны, но по моему мнению уже не из разряда элементарных предикатов, а немного продвинутых, так как используют кортежи (tuple) и списки кортежей:
Visual Prolog Код:
implement main open core, console, list constants className = "main". classVersion = "$JustDate: $$Revision: $". class predicates clauses classInfo(className, classVersion). run():-init(), T2=zip([1,2,3],["asd","zxc","qwe"]), write("zip2: ",T2), nl, T3=zip([1,2,3],["asd","zxc","qwe"],['\u2194','\u0066','\u203C']), write("zip3: ",T3), nl, write("\nнедетерминированные zip-ы:"),nl, foreach Q=zipHead_nd([1,2,3],["а","б","в","г","д"]) do write(Q," -> ") end foreach, nl, foreach W=zipHead_nd([1,2,3,4,5,6,7,8],["а","б","в","г"]) do write(W," -> ") end foreach, nl, foreach E=zip_nd([1,2,3],["а","б","в"]) do write(E," -> ") end foreach, nl, foreach G=zip_nd([1,2,3],["asd","zxc","qwe"],['\u2194','\u0066','\u203C']) do write(G," -> ") end foreach, nl, unzip(T2,A,B), write("\nunzip: ",A," ~ ",B),nl, unzip(T3,Z1,Z2,Z3), write("unzip: ",Z1," ~ ",Z2," ~ ",Z3),nl, _=readline().
end implement main
goal mainExe::run(main::run).
Обратите внимание, что в списке символов ['\u2194','\u0066','\u203C'] использованы unicode, но здесь форумный движок отображает их криво.
Предикат zipHead_nd обрезает хвост того списка(ов), который длиннее, т.е. идёт выравнивание длины по наикороткому списку.
Результаты:
Цитата:
zip2: [tuple(1,"asd"),tuple(2,"zxc"),tuple(3,"qwe")]
zip3: [tuple(1,"asd",'-'),tuple(2,"zxc",'f'),tuple(3,"qwe",'!')]
недетерминированные zip-ы:
tuple(1,"а") -> tuple(2,"б") -> tuple(3,"в") ->
tuple(1,"а") -> tuple(2,"б") -> tuple(3,"в") -> tuple(4,"г") ->
tuple(1,"а") -> tuple(2,"б") -> tuple(3,"в") ->
tuple(1,"asd",'-') -> tuple(2,"zxc",'f') -> tuple(3,"qwe",'!') ->
unzip: [1,2,3] ~ ["asd","zxc","qwe"]
unzip: [1,2,3] ~ ["asd","zxc","qwe"] ~ ['-','f','!']
|
Кортежи tuple(...) объявлены в VIP так, что могут иметь от 2 до 12 аргументов.
Сами zip-ы и unzip-ы определены очень просто, например unzip:
Visual Prolog Код:
unzip([], [], []). unzip([tuple(A, B)|ABL], [A|Al], [B|Bl]):-unzip(ABL, Al, Bl).
Но они определены только для двух и трёхарных кортежей. Однако ничего не стоит сделать ручками любую арность, например четырёхарные кортежи:
Visual Prolog Код:
unzip([], [], [], [], []). unzip([tuple(A, B, C, D)|L], [A|Al], [B|Bl], [C|Cl], [D|Dl]) :- unzip(L, Al, Bl, Cl, Dl).
|
|
|
Флудер
Сообщений: 3,170
Сказал(а) спасибо: 6
Поблагодарили 16 раз(а) в 15 сообщениях
Регистрация: 28.02.2005
Адрес: Израиль
|

05.02.2012, 17:15
Вспомнил про прикольный способ определения unzip через zip в Питоне, сейчас у себя тоже тисну.
Цитата:
>>> def unzip(lst): return zip(*lst)
>>> x=zip((1,2,3),("a","b","c"),([],[[]],[[[]]]))
>>> x
[(1, 'a', []), (2, 'b', [[]]), (3, 'c', [[[]]])]
>>> unzip(x)
[(1, 2, 3), ('a', 'b', 'c'), ([], [[]], [[[]]])]
|
|
|
|
Специалист
Сообщений: 8,170
Сказал(а) спасибо: 5
Поблагодарили 339 раз(а) в 338 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
|

05.02.2012, 17:19
Списки. Продолжение.
На закуску высокоуровневые предикаты обработки списков. В Visual Prolog аргументом предиката может быть другой предикат, который должен быть объявлен по особому - как предикатный домен или функциональный домен, в зависимости от задачи. Кроме этого, такой предикат второго порядка может быть исполнен как анонимный предикат (лямбда-предикат).
Я покажу основные высокоуровневые предикаты, остальные можете посмотреть в хэлпе к классу list.
Поехали, космонавты!
1. Декомпозиция списка на несколько подсписков по заданным критериям. Здесь я реализую функцию signum, то бишь знак числа.
Предикат второго порядка определён двумя способами, как явно заданный предикат fff и как анонимный предикат (в фигурных скобках). Результат работы обоих вариантов конечно же одинаков  :
Visual Prolog Код:
implement main open core, console, list constants className = "main". classVersion = "$JustDate: $$Revision: $". class predicates fff : (integer) -> integer. % <- вот это описание мне до боли напомнило хаскель clauses classInfo(className, classVersion).
fff(A)=1:-A>0,!. fff(A)=0:-A=0,!. fff(_)=-1.
run():-init(), write(decompose([-4,-3,-2,-1,0,1,2,3,4],fff)),nl, write(decompose([-4,-3,-2,-1,0,1,2,3,4],{(A)=Z:-A>0,Z=1,!;A=0,Z=0,!;Z=-1})), _=readline().
end implement main
goal mainExe::run(main::run).
Результат:
Цитата:
[tuple(-1,[-1,-2,-3,-4]),tuple(0,[0]),tuple(1,[4,3,2,1])]
[tuple(-1,[-1,-2,-3,-4]),tuple(0,[0]),tuple(1,[4,3,2,1])]
|
Этот предикат fff можно объявить с вывертом  , через предикатный домен. Для этого надо вместо вот этого объявления:
Visual Prolog Код:
class predicates fff : (integer) -> integer.
вставить вот это объявление:
Visual Prolog Код:
domains ddd{A} = (A) -> A. % <- это отображение типов само является типом ddd (чем не хаскель?) class predicates fff : ddd{integer}.
Здесь в фигурных скобках передаётся домен параметра.
Бежим дальше, но теперь в кратких исходниках, без текста всего консольного проекта.
2. Тест хотя бы одного элемента
Visual Prolog Код:
class predicates fff : (integer) determ. clauses fff(A):-A>5.
run():- exists([1,2,3,4,5,6,7,8,9],fff), exists([1,2,3,4,5,6,7,8,9],{(A):-A>5}), write("exist");
Результат: так как в списке есть число >5, то будет напечатано exist
3. Фильтрация
Visual Prolog Код:
class predicates fff : (integer) determ. clauses fff(A):-A>5.
run():- filter([1,2,3,4,5,6,7,8,9],fff,A,B), write(A," ",B), filter([1,2,3,4,5,6,7,8,9],{(C):-C>5},A1,B1), write(A1," ",B1),
Результат:
Цитата:
[6,7,8,9] [1,2,3,4,5]
[6,7,8,9] [1,2,3,4,5]
|
4. Сборка
Visual Prolog Код:
class predicates fff : (integer,integer) -> integer. clauses fff(A,B)=A*B.
run():- write(fold([1,2,3],fff,10)),nl, write(fold([1,2,3],{(A,B)=A+B},10)),
Результат:
5. Для всех
Visual Prolog Код:
forAll([1,2,3,4,5,6,7,8,9],{(A):-write(A*A," ")}),
Результат:
6. Преобразование списка, map, хрен его знает как по-русски грамотно перевести
Visual Prolog Код:
write(map([1,2,3,4,5,6,7,8,9],{(A)=A*A})),
Результат:
Цитата:
[1,4,9,16,25,36,49,64,81]
|
7. Упаковка списков, была уже, но ещё раз, с подвывертом.
Например так: найти буквы, ключи которых (в первом списке) >2
Visual Prolog Код:
write([ B || tuple(A,B)=zip_nd([1,2,3,4],['a','b','c','d']),A>2] ),
Результат:
Чего не понятно - спрашивайте. Отвечать гораздо легче, чем писать обзор.
|
|
|
Специалист
Сообщений: 8,170
Сказал(а) спасибо: 5
Поблагодарили 339 раз(а) в 338 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
|

05.02.2012, 17:27
Цитата:
Сообщение от gromozeka
Вспомнил про прикольный способ определения unzip через zip в Питоне, сейчас у себя тоже тисну.
|
А в VIP zip определён через недетерминированный zip с помощью коллектор списка:
zip(AL, BL) = [T || T = zip_nd(AL, BL)].
Кстати, я в примерах не использовал коллектор списка [...||...] специально. Планирую о нём рассказать подробно, если кто не знает его особенностей.
|
|
|
Member
Сообщений: 312
Сказал(а) спасибо: 12
Поблагодарили 1 раз в 1 сообщении
Регистрация: 26.03.2004
Адрес: Москва
|

05.02.2012, 18:32
Цитата:
Сообщение от Винитарх
Поэтому основы, т.е. что такое предикат, факты БД, сопоставление с образцом (pattern matching) и поиск с возвратом (он же бактрекинг, он же backtracking) я не рассказываю. Но режимы детерминизма я покажу. Однако, если кому-то надо пояснить суть предикатов, сопоставления с образцом и бактрекинга, я готов.
|
Мне давно хотелось спросить по поводу этих понятий. Я прочитал в Братко о механизмах поиска в глубину, в ширину, но так и не понял - нужно это реализовывать ручками? Или можно только задать базу знаний и определить цель, а сам Пролог выдаст результат? Как-то не очень хочется механизмы поиска программировать самому с возможными ошибками, а хотелось бы положиться на специалистов, которые запрограммировали эти механизмы. Это же касается обратного и прямого логического вывода, логического программирования с ограничениями и т.д.
Последний раз редактировалось tumanovalex; 05.02.2012 в 18:39
|
|
|
Специалист
Сообщений: 8,170
Сказал(а) спасибо: 5
Поблагодарили 339 раз(а) в 338 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
|

05.02.2012, 18:41
В Прологах реализован поиск вглубь, он ещё называется поиск с возвратом, он же бэктрекинг. Поэтому ручками писать его не надо. Надо правильно составить правила, чтобы поиск с возвратом сам нашёл решение.
|
|
|
Member
Сообщений: 312
Сказал(а) спасибо: 12
Поблагодарили 1 раз в 1 сообщении
Регистрация: 26.03.2004
Адрес: Москва
|

05.02.2012, 19:05
Спасибо за ответ. А в Братко описание механизмов вывода приводится для более глубокого понимания вывода Прологом заключений?
|
|
|
Специалист
Сообщений: 8,170
Сказал(а) спасибо: 5
Поблагодарили 339 раз(а) в 338 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
|

05.02.2012, 20:37
Я не знаю что там у Братко написано. В старое издание я не заглядывал лет 15, а новое не приобретал - мне оно не нужно.
Могу сказать от себя, что существует три способа реализации машины вывода - вглубь, вширь и эвристический. Каждый из них ещё разделяется на ряд разновидностей. В англоязычной википедии об этом хорошо написано. Классический Пролог использует поиск вглубь. Сто лет назад был ParLog (параллельный Пролог). Вроде он искал вширь.
Однако с помощью поиска вглубь и коллектора решений легко реализовать поиск вширь и любую разновидность эвристического поиска.
|
|
|
ушёл... не вернётся)))
Сообщений: 3,400
Сказал(а) спасибо: 0
Поблагодарили 82 раз(а) в 82 сообщениях
Регистрация: 29.11.2008
|

05.02.2012, 23:39
Цитата:
Сообщение от Винитарх
Я не знаю что там у Братко написано. В старое издание я не заглядывал лет 15, а новое не приобретал - мне оно не нужно.
|
Мне тоже не нужно. Я и лет 15 назад "плюнул". Но: или есть чего про Пролог причитать кроме этого "Фенимора Куппера"("Жулля Верна"\"Майн Рида"\.....)?!)))))))))))
Цитата:
Сообщение от Винитарх
Однако с помощью поиска вглубь и коллектора решений легко реализовать поиск вширь и любую разновидность эвристического поиска.
|
Ещё классы, массивы... О-ё-ё-ёй)))
|
|
|
Специалист
Сообщений: 8,170
Сказал(а) спасибо: 5
Поблагодарили 339 раз(а) в 338 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
|

06.02.2012, 00:02
Цитата:
Сообщение от aag
Но: или есть чего про Пролог причитать кроме этого "Фенимора Куппера"("Жулля Верна"\"Майн Рида"\.....)?!)))))))))))
|
iso-шные Прологи по сравнению с Visual Prolog практически не развиваются. И читать по ним что-либо просто неинтересно, да и нечего. Ну а про Visual Prolog читать было бы интересно, да нечего. Англоязычные книги написаны для ... (лучше промолчать). Русскоязычные книги по версии 7.3 отсутствуют. Может вскорости, судя по всему, Alison издаст. Я пишу, но малыми темпами, и когда разрожусь не знаю.
|
|
|
Member
Сообщений: 312
Сказал(а) спасибо: 12
Поблагодарили 1 раз в 1 сообщении
Регистрация: 26.03.2004
Адрес: Москва
|

06.02.2012, 00:26
Очень было интересно узнать мнение специалистов о VIP и книги Братко. После ее прочтения мне показалось, что мне этого никогда не осилить и Пролог не для моего понимания  .
|
|
|
Member
Сообщений: 4,798
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
|

06.02.2012, 18:44
Цитата:
Сообщение от Винитарх
iМожет вскорости, судя по всему, Alison издаст.
|
Пожалуйста, не пиши больше ничего о том, когда я издам. Не вводи людей в заблуждение. Я пока понятия не имею, даже когда я ее закончу, а не только о том, когда приступлю к изданию, что само по себе тоже процесс долгий. Но когда он начнется - представления не имею.
Последний раз редактировалось Alison; 06.02.2012 в 18:48
|
|
|
Member
Сообщений: 4,798
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
|

06.02.2012, 18:47
Цитата:
Сообщение от tumanovalex
Очень было интересно узнать мнение специалистов о VIP и книги Братко. После ее прочтения мне показалось, что мне этого никогда не осилить и Пролог не для моего понимания  .
|
Visual Prolog - прекрасный продукт и заведомо хороший инструмент для быстрого прототипирования различных систем, например. Особенно если говорить о стадии изучения.
Книга Братко - хорошая книга, мне нравится. Для изучения Visual Prolog ее не достаточно, понадобится также документация, которой много на сайте разработчика.
|
|
|
Опции темы |
|
Опции просмотра |
Линейный вид
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
|