LINUX.ORG.RU

[функциональщина тред][вопрос к специалистам] что выбрать?


0

1

На работе занимаюсь обработкой текстов на естественном языке.

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

С переходом на следующий уровень (синтаксический анализ, автоматическая генерация правил, синтез исходных понятий и т.д.) стало ясно что количество «матана» начинает зашкаливать и реализовывать это «в лоб» (на С++) конечно можно попробовать, но будет грустно и непродуктивно. Соответственно появилась идея попробовать решить задачу в функциональном стиле, есть ощущение что решение получится красивое и волне себе лаконичное.

А раз так, задумался я над тем какой язык выбрать для реализации. Собрав задницу в кулак и мозг в голову, я прошерстил интернет на предмет того каким решением можно воспользоваться в данной области, по результатам были отобраны следующие языки: Prolog, OCaml, Lisp, Scheme, Haskell и, как это ни странно, Python и Erlang.

Маленькое уточнение: требуется кроссплатформенное решение (windows, linux, macos) с возможностью компиляции в байт-код, хорошо бы иметь потоки, GUI не особо нужны, но будут плюсом, ide - неважно. Ещё один важный момент: наличие коммерческих реализаций с целью дальнейшего на них перехода или, как вариант, серьёзного бэкграунда.

Понятно, что на любом из этих языков можно реализовать всё что угодно, посему оценивались больше практические моменты использования, так вот, поковырявшись с вышеперечисленными языками я сделал для себя следующие выводы о готовности их к использованию в production:

  • Prolog - собственно существуют довольно вменяемые открытые и коммерческие реализации, однако общее состояние дел большее напоминает заброшенную ферму (например, разные реализации интерпретатора могут использовать разный синтаксис).
  • OCaml - неплохой претендент, немного стагнирует в своём развитии, но имеет существенную поддержку в лице INRIA (и небольшой буст со стороны в виде F#).
  • Lisp - весьма разносторонний язык, есть весьма вменяемая свободная реализация (Clozure CL; SBCL, увы, *nix oriented) и мега-буст с точки зрения коммерческих реализаций (Allegro CL, LispWorks), есть так же реализация под Java VM.
  • Scheme - сводный брат Lisp, ситуация обстоит приблизительно так же, хотя непонятно что с коммерческими реализациями и вообще Scheme имеет репутацию академического языка.
  • Haskell - довольно молодая и таки тёмная лошадка, есть некоторый зоопарк в реализациях, коммерческие средства отсутствуют, присутствует некоторый перекос ориентации в сторону *nix.
  • Python - довольно годный язык, но поддержка функциональной парадигмы там реализована довольно слабо + наличествуют всякие выкрутасы (типа GIL).
  • Erlang - годный Prolog-like язык, но меня смущает его ориентация на телеком.

Как то вот так у меня получилось (большого опыта работы с данными языками у меня нет, так что, если я где в оценке промахнулся, просьба тыкнуть меня носом :)).

Сам пока склоняюсь к Lisp.

Собственно, товарищи опытные функциональщики, нужен Ваш совет относительно данной ситуации, что бы использовали Вы (что использовали Вы), что будет более/менее годное для решения подобного класса задач, какие есть подводные камни. И, самое главное, какие по Вашему мнению языки вляются более перспективными, на какие в первую очередь стоит тратить своё время.

Уф! Дописал. Всем откликнувшимся большое спасибо заранее. :)

ЗЫ brainf*ck и иже с ним не предлагать.

★★★★★

Ответ на: комментарий от ahonimous

тут что-то не видно вакансий на лиспе, как в прочем и в других местах

вот тебе пара вакансий в ДС

http://undev.ru/position/c-developer.html

http://undev.ru/position/erlang-developer.html

правда что за контора не розумию :)

shty ★★★★★
() автор топика
Ответ на: комментарий от shty

> вот тебе пара вакансий в ДС

http://undev.ru/position/c-developer.html

http://undev.ru/position/erlang-developer.html



c-developer + erlang-developer - а где там лисп то? по ссылкам прошелся - единственное упоминанание лиспа в одной вакансии, во фразе, что хорошо, если есть наличие опыта с "..... лиспы и т. п. экзотика" :)

ahonimous
()
Ответ на: комментарий от ahonimous

c-developer + erlang-developer - а где там лисп то?

тебе шашечки или ехать? :)

shty ★★★★★
() автор топика
Ответ на: комментарий от shty

>а теперь задумайтесь над тем сколько уйдёт времени и строчек кода для решения простейшей задачи вида

Кода уйдет не так уж много. Вся задача сводится к генерации перестановок и проверке условия.

Код на C++ (54 строки):

#include <algorithm>
#include <iostream>

enum husband {ED, FRANK, GEORGE, HARRY};
enum wife {BETTY, ALICE, CAROL, DOROTHY};

static const char *name_h[] = {"ED", "FRANK", "GEORGE", "HARRY"};
static const char *name_w[] = {"BETTY", "ALICE", "CAROL", "DOROTHY"};

struct sample {
    enum wife       wife[4];    // отношение "мужчина состоит в браке с"
    enum husband    husband[4]; // отношение "женщина состоит в браке с"
    enum wife       dance_w[4]; // отношение "мужчина танцует с"
    enum husband    dance_h[4]; // отношение "женщина танцует с"
};

static int check(const struct sample &s)
{
    if (s.dance_h[BETTY] == ED &&
        s.dance_h[ALICE] == s.husband[CAROL] &&
        s.dance_h[DOROTHY] == s.husband[ALICE] &&
        s.dance_w[FRANK] == s.wife[GEORGE] &&
        s.dance_w[GEORGE] == s.wife[ED])
        return 1;
    return 0;
}

static void dump_solution(const struct sample &s)
{
    for (int i = 0; i < 4; i++) {
        std::cout << name_h[i] << " married on " << name_w[s.wife[i]] << " dance with " << name_w[s.dance_w[i]] << std::endl;
    }
}

int main()
{
    struct sample s;
    for (int i = 0; i < 4; i++)
        s.wife[i] = (enum wife)i;
    do {
        for (int i = 0; i < 4; i++) {
            s.husband[s.wife[i]] = (enum husband)i;
            s.dance_w[i] = (enum wife)i;
        }
        do {
            for (int i = 0; i < 4; i++)
                s.dance_h[s.dance_w[i]] = (enum husband)i;
            if (check(s))
                dump_solution(s);
        } while (std::next_permutation(s.dance_w, s.dance_w + 4));
    } while (std::next_permutation(s.wife, s.wife + 4));
    return 0;
}

Нагугленный код на прологе (41 строка):

domains
p=p(symbol,symbol,symbol)
predicates
nondeterm hus(symbol)
nondeterm dance(symbol,symbol)
nondeterm married(symbol,symbol)
nondeterm solve(p,p,p,p)
determ check(symbol,symbol)
clauses
solve(p(betty,HusB,ed),p(alice,HusA,HusC),
        p(carol,HusC,X),p(doroty,HusD,HusA)):-
    hus(HusB),
    married(betty,HusB),
    hus(HusA),HusA<>HusB,
    married(alice,HusA),    
    hus(HusC),HusC<>HusB,HusC<>HusA,
    married(carol,HusC),    
    check(HusA,HusC),
    hus(HusD),HusD<>HusC,HusD<>HusB,HusD<>HusA,  
    married(doroty,HusD),
    check(HusD,HusA),
    hus(X),X<>"ed",X<>HusA,X<>HusC,
    check(HusC,X).

check(george,P):- !,P="frank".
check(ed,P):- !,P="george".
check(_,_).

hus(ed).
hus(frank).
hus(george).
hus(harry).

dance(betty,ed):- !.
dance(alice,X):- married(carol,X).
dance(doroty,X):- married(alice,X).
dance(X,frank):- married(X,george).
dance(X,george):- married(X,ed).

married(W,H):- not(dance(W,H)).
goal
solve(B,A,C,D).

При этом в C++ 8 строк служат непосредственно для вывода результата, что в прологе делается за нас. Итого 46 строк на C++ (из которых 2 — это #include и еще две являют собой необходимость определения символьных констант, чтобы не запутаться в функции проверки условия) против 41 строки на прологе. По-моему неплохо.

linuxfan
()
Ответ на: комментарий от linuxfan

Это TurboProlog?! Давай код на обычном прологе без всяких clauses, predicates и nondeterm. Это раз.

И еще от тебя эквивалент на Си++ с таким же алгоритмом перебора. Полный перебор через std::next_permutation выглядит неспортивно! Это два.

dave ★★★★★
()
Ответ на: комментарий от Love5an

>Гы. Я, кстати, подумываю стартап начать. С использованием CL.

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

linuxfan
()
Ответ на: комментарий от dave

>Это TurboProlog?! Давай код на обычном прологе без всяких clauses, predicates и nondeterm. Это раз.

Читай внимательно: я этот код нагуглил. Знаешь пролог, так напиши.

И еще от тебя эквивалент на Си++ с таким же алгоритмом перебора.

Я никому ничего не должен. Особенно я не должен «такой же алгоритм перебора, как в прологе».

Полный перебор через std::next_permutation выглядит неспортивно!

Решение получено за приемлемое время? Да. Чего тебе еще надобно?

linuxfan
()
Ответ на: комментарий от linuxfan

> Если бы мне пришло в голову связаться со стартапом, то я бы его делал для получения коммерческой выгоды. Да, не понять мне лиспофилов-технократов.

с таким унылым стартапом, ты обречен.

CL-USER
()
Ответ на: комментарий от dave

>Твое сравнение некорректно.

Некорректно печатать предварительно посчитанный ответ. Полный перебор является корректным решением.

linuxfan
()
Ответ на: комментарий от linuxfan

Сначала прокомментирую код на прологе - это вообще не решение задачи. Человек, который это писал явно носит на собственных ушах лапшу «стоит только описать условия и все само решится». Собственно, он так и попытался сначала, а когда ничего не заработало он начал лепить костыли. Появились какие-то захардкоденные имена, появился предикат check. Итого, задачу автор решил руками, а не на прологе; чуть изменятся условие и его решение работать перестанет.

Что касается решения на плюсах, это, безусловно решение, так как ответ верный есть. Но это никуда не годится в контексте треда, человек dsl'и собрался писать, а тут такая порнография. Опять же куча всего захардкоденного, куча синсаксического мусора. Как модифицировать такую программу? Как добавить новое условие, например?

Предлагаю кому-нибудь попытаться повторить на плюсах что-нибудь такое, а потом уже меряться строчками:

%%%%% Description
men([ed, frank, george, garry]).
women([betty, alice, dorothy, caroll]).

rule([(ed,_,betty)]).
rule([(_,caroll,alice)]).
rule([(_,alice,dorothy)]).
rule([(frank,_,X), (george,X,_)]).
rule([(george,_,X), (ed,X,_)]).

%%%%% Solver
solve(Solution) :-
        men(M), women(W),
        prepare_check(Solution, CheckSolution),
        generate_solution(M,W,Solution),
        call(CheckSolution).

generate_solution(Men,Women,Solution) :-
        permutation(Women,Wives), permutation(Women,Partners),
        maplist(\=,Wives,Partners),
        zip3(Men,Wives,Partners,Solution).

prepare_check(Solution, Goal) :-
        findall(R,rule(R),Rs),
        maplist(rule_to_goal(Solution),Rs,Gs),
        list_to_tuple(Gs,Goal).

rule_to_goal(S,R,G) :-
        maplist(create_goal(S),R,Gs),
        list_to_tuple(Gs,G).

create_goal(S,R,G) :- G =.. [member,R,S].

%%%% Utilities
list_to_tuple([X|Xs],(X,Ys)) :- list_to_tuple(Xs,Ys), !.
list_to_tuple([X],X).

zip3(L1,L2,L3,Z) :- maplist(zip3_,L1,L2,L3,Z).
zip3_(X1,X2,X3, (X1,X2,X3)).
Это то, о чем я писал несколькими постами ранее: отдельно описание в свободной форме, отдельно «решатель».

dmsh
()
Ответ на: комментарий от dmsh

>Как добавить новое условие, например?

Просто изменить функцию check.

Предлагаю кому-нибудь попытаться повторить на плюсах что-нибудь такое, а потом уже меряться строчками:

Во-первых, у тебя такой же перебор, как и в плюсах, так что повторять особо нечего.

Во-вторых, хорошо, что задача имеет единственное решение даже без ограничения «никто не танцует со своей женой».

В-третьих, это по эффективности раза в 3-4 будет хуже плюсов по одной единственной причине создания кучи ненужных объектов.

Это то, о чем я писал несколькими постами ранее: отдельно описание в свободной форме, отдельно «решатель».

Если присмотреться, в плюсовом примере все описание сосредоточено в check.

linuxfan
()
Ответ на: комментарий от linuxfan

Во-первых, у тебя такой же перебор, как и в плюсах, так что повторять особо нечего

К алгоритму претензий вообще никаких, наплевать на него, дело не в алгоритме.

Во-вторых, хорошо, что задача имеет единственное решение даже без ограничения «никто не танцует со своей женой».

Хорошо для кого? У меня в коде эта проверка есть (и занимает она ровно одну строчку), а вот в плюсовом я ее что-то не наблюдаю.

В-третьих, это по эффективности раза в 3-4 будет хуже плюсов по одной единственной причине создания кучи ненужных объектов.

Я предлагаю отложить обсуждение эффективности (особенно в широком смысле слова, ага) до того момента как мы увидим аналогичную программу на плюсах. Эта уловка крестовиков мне хорошо знакома: «ну и что, что криво и падает через раз, зато мы байты быстро перемалываем».

Если присмотреться, в плюсовом примере все описание сосредоточено в check.

Дело в том что это не _описание_, а вручную закодированный тобой готовый алгоритм. И именно в этом месте происходит все самое интресное: как из _описаний_ вида [(george,_,X), (ed,X,_)] получить _код_, который делает соответствующие проверки.

Итого, у меня полноценный dsl на прологе уместился в половину объема, занимаемого плюсовой программой с одним захаркоденным по самые гланды частным случаем.

dmsh
()
Ответ на: комментарий от dmsh

>Хорошо для кого? У меня в коде эта проверка есть (и занимает она ровно одну строчку), а вот в плюсовом я ее что-то не наблюдаю.

Честно говоря, не вижу этой строчки. В плюсах это будет выглядеть как

for(i = 0; i < 4; i++)
    s.wife[i] != s.dance_w[i]

>И именно в этом месте происходит все самое интресное: как из _описаний_ вида [(george,_,X), (ed,X,_)] получить _код_, который делает соответствующие проверки.

Дело в том, что в плюсах и код-то получать незачем, он самоочевиден: s.dance_h[BETTY] == ED — Бетти танцует с Эдом, s.dance_h[ALICE] == s.husband[CAROL] — Алиса танцует с мужем Кэрол и так далее. Н ахудой конец, можно сделать

template<typename T> dance_with(const T a, const T b) {return a == b;}
Или даже
#define dance_with ==
Тогда описание условия будет до безобразия приближено к естественному языку (и к предметной области). В отличии от Prolog, где для меня остаются загадкой «_» и «X».

>Итого, у меня полноценный dsl на прологе уместился в половину объема, занимаемого плюсовой программой с одним захаркоденным по самые гланды частным случаем.

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

linuxfan
()
Ответ на: комментарий от linuxfan

Честно говоря, не вижу этой строчки.

maplist(\=,Wives,Partners)

описание условия будет

Еще раз, это не описание. Описание - это данные, а код это код. У меня код по заданным описаниям строится программно (программа, которая пишет программу), ты же пишешь его руками.

В отличии от Prolog, где для меня остаются загадкой «_» и «X».

Там можно поколдовать над языком описания, я не хочу этого делать, т.к. принципиального значения вид его не имеет. Сейчас каждое правило это просто список кортежей. [(george,_,X), (ed,X,_)] означает: есть некто Х, этот Х танцует с джорджем и приходится женой эду, с кем танцует эд и кто замужем за джорджем - не важно.

Можно было бы наопределять своих операторов и писать например как-нибудь так:

george dance_with X and ed husband_of X.
Это дало бы нам терм and(dance_with(george,X), husband_of(ed,X)), преобразовать который к существующему формату (списку кортежей) - дело техники.

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

Алгоритм у меня построен под задачу, где состав участников и правила могут меняться, ты захардкодил кусок под этих конкретных участников и эти конкретные правила.

Ты до сих пор не понимаешь разницы, а она принципиальная. Чтобы ты ее лучше прочувствовал представь, что все входные данные (имена участников и ограничения) загружаются из файла. У меня изменится только prepare_check, где вместо выбора описаний из базы findall(R,rule(R),Rs) появится какой-нибудь read_rules_from_file(File,Rs). Как изменится твоя?

dmsh
()
Ответ на: комментарий от dmsh

>Алгоритм у меня построен под задачу, где состав участников и правила могут меняться, ты захардкодил кусок под этих конкретных участников и эти конкретные правила.

Пффф, ты притворяешься или правда не понимаешь эквивалентности твоих rules и моего check? То, что в твоем варианте это, якобы, данные, а в моем вроде как код разница крайне непринципиальная. Более того, если в плюсовом варианте добавить перегруженные методы spouse и partner, станет окончательно очевидно, что декларативный пролог шумно слил по внятности, как ты его назвал, dsl.

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

Еще один «одепт» изотерического программирования? Я предоставил пример того, что решение задачи на плюсах выглядит вполне наглядно (наглядней, чем на прологе, кстати). Ты в общие случаи полез, потому что ощутил, что в частных пролог как-то невыразительно смотрится?

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

linuxfan
()
Ответ на: комментарий от dmsh

>Пример чтения из файла будет или нет?

Хочешь понтануться возможностью пролога подгружать внешние файлы? Это так смешно, что даже смешно.

linuxfan
()
Ответ на: комментарий от dmsh

>Слив засчитан, следующий.

FYI: я засчитал тебе слив еще когда ты представил велосипедное решение задачи на прологе с ручным перебором, но тактично промолчал.

linuxfan
()
Ответ на: комментарий от linuxfan

Ответ получен? Получен. Никакого ручного перебора там нет, кстати, это уже твои фантазии. И хоть программа на прологе оказалась короче, я согласен на ничью в первом раунде. Головоломку все кое-как решили.

Раунд два: задача та же, но условия(участники и кто на ком стоялженат) читаются из файла, формат данных в файле - любой текстовый.

Крестоносцы начинают. Вперед!

dmsh
()
Ответ на: комментарий от dmsh

Крестоносцы начинают

Разумеется, в одну калитку играть не интересно. Поэтому я даю честное слово декларативного сектанта, что после того как задача будет решена на крестах, я запощу полное решение на прологе с более приличным форматом входных данных (как показал несколькими постами выше) и честным чтением из файла.

dmsh
()
Ответ на: комментарий от linuxfan

FYI: я засчитал тебе слив еще когда ты представил велосипедное решение задачи на прологе с ручным перебором, но тактично промолчал.

прежде чем засчитывать другим слив неплохо бы Вам для начала подумать немножко и понять что Вам говорят, также неплохо было бы Вам прочитать о чём речь идёт в данном топике

shty ★★★★★
() автор топика
Ответ на: комментарий от dmsh

кстати, большое спасибо за наглядную демонстрацию :)

shty ★★★★★
() автор топика
Ответ на: комментарий от dmsh

>Крестоносцы начинают. Вперед!

формат данных в файле - любой текстовый

[fat]Я выбираю enum'ы и check в *.h файле, который инклюдится и компилируется каждый раз[/fat]

Ну а вообще мне было бы любопытно посмотреть, как ты запишешь правило «никто не танцует со своей женой/мужем». Оно-то у тебя захардкожено.

linuxfan
()
Ответ на: комментарий от shty

>о чём речь идёт в данном топике

О DSL и ниасиляторах, не понимающих, что построить абстракции предметной области и манипулировать ими можно в любом языке, даже на ассемблере. Язык будет влиять только на «многословность» построения таких абстракций и описания их взаимодействия.

Тем, кто собрался использовать LISP для обработки символьной информации не мешало бы для начала попроовать работать там со строками. Это такой стыд, что непонятно, почему скобкофилов в каждом холиваре не тычут носом в это безобразие.

linuxfan
()
Ответ на: комментарий от linuxfan

[fat]Я выбираю enum'ы и check в *.h файле, который инклюдится и компилируется каждый раз[/fat]

Куда там, каждый раз компилировать нельзя - нужно считывать из файла и делать eval прямо в run-time :) C++ выбывает из списка ?)

quasimoto ★★★★
()
Ответ на: комментарий от linuxfan

> Тем, кто собрался использовать LISP для обработки символьной информации не мешало бы для начала попроовать работать там со строками. Это такой стыд, что непонятно, почему скобкофилов в каждом холиваре не тычут носом в это безобразие.

можно поподробнее? или ссылку на соответствующий пост из какого-нибудь каждого холивара

korvin_ ★★★★★
()
Ответ на: комментарий от linuxfan

> Тем, кто собрался использовать LISP для обработки символьной

информации не мешало бы для начала попроовать работать там

со строками.


Отлично там всё со строками, во время последнего большого холивара Perl был уделан по полной программе.

> Это такой стыд, что непонятно, почему скобкофилов в каждом

холиваре не тычут носом в это безобразие.


Не надо бредить о том, в чём не разбираетесь.

archimag ★★★
()
Ответ на: комментарий от quasimoto

>Куда там, каждый раз компилировать нельзя - нужно считывать из файла и делать eval прямо в run-time :) C++ выбывает из списка ?)

Компилировать динамически подгружаемую библиотеку, а затем подгружать ее. Помни, что на C и C++ написано большинство фантастически расширяемых вещей, как то: Linux kernel, Explorer и т. д.

linuxfan
()
Ответ на: комментарий от Rastafarra

Вообще-то автор топика писал что ``пока задача сформулирована в общих фразах, что-то вроде типа «автоматическая генерация правил для семантического анализа текста»" а также ``пока ещё никто не представил устойчивого решения данной проблемы, отдельные вещи есть, условно работают, но именно что «условно»". Были представлены только частичные решения на двух языках. Так что задача сформулирована не была. Но если что - я могу посмотреть.

З.Ы. или вы потролить пришли ? :)

quasimoto ★★★★
()
Ответ на: комментарий от archimag

>Отлично там всё со строками, во время последнего большого холивара Perl был уделан по полной программе.

Ты cl-ppcre чтоли имеешь в виду? Я вообще-то говорю о ручной работе со строками.

Не надо бредить о том, в чём не разбираетесь.

Разбираюсь, поверь.

linuxfan
()
Ответ на: комментарий от quasimoto

>Озвучте задачу, плиз.

Эд, Франк, Джордж и Гарри пригласили своих жен в вечерний клуб на танцы и для разнообразия решили, что каждый будет танцевать с женой другого. В результате Бетти танцевала с Эдом, Алиса - с мужем Кэрол, Дороти - с мужем Алисы, Франк - с женой Джорджа, а Джоржд - с женой Эда. Кто на ком женат? Кто с кем танцевал?

Специальная олимпиада разворачивается вокруг «напишите решатель для подобного класса задач».

linuxfan
()
Ответ на: комментарий от linuxfan

Linux kernel

4.2 - ядро линукс псевдо-модульное ядро - если карта моих модулей не совпадает с новым модулем, то мне приходится пересобирать ядро чтобы была новая карта модулей. Пример - собирали без поддержки виртуализации, нет бы просто собрать модуль - так нужно всё ядро пересобирать. Один человек в блоге писал, что в истории разработки ОС это пройденый этап и для Linux тоже могла быть реализована полная модульность (нет, не на «лиспе» :) на том же Си).

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

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

Были представлены только частичные решения на двух языках. Так что задача сформулирована не была.

тред перечитай, да. хотя бы 4-ю страницу.

Rastafarra ★★★★
()
Ответ на: комментарий от quasimoto

> C++ выбывает из списка ?)

способ решения через перебор был показан, распарсить файл + заменить enum на вектор - несложно, заменить захардкоденную проверку на цикл - тоже, но да - решение станет раза в два больше, ну и ( барабанная дробь ) никто не мешает на С++ писать в стиле пролога:

http://www.cc.gatech.edu/~yannis/lc++/
http://www.cc.gatech.edu/~yannis/lc++/family_cc_snippet.txt

и таких библиотек хватает

ahonimous
()

shty, насчёт «автоматическая генерация правил для семантического анализа текста» - в качестве грамматик будут использоваться грамматики Хомского или что-то посложне?

quasimoto ★★★★
()
Ответ на: комментарий от linuxfan

> Я вообще-то говорю о ручной работе со строками.

И что не так с ручной работой со строками? Кстати, в каком ещё языке есть сопоставимая поддержка UNICODE?

Разбираюсь, поверь.


Что-то не похоже. Кстати, пожалуйста, уточняй о каком именно «лиспе» идёт речь, лично я говорю о Common Lisp.

archimag ★★★
()
Ответ на: комментарий от linuxfan

О [..] ниасиляторах, не понимающих, что построить абстракции предметной области и манипулировать ими можно в любом языке, даже на ассемблере.

читаем исходное сообщение, читаем

реализовывать это «в лоб» (на С++) конечно можно попробовать, но будет грустно и непродуктивно

Язык будет влиять только на «многословность» построения таких абстракций и описания их взаимодействия.

вот нифига, С++, к примеру, не позволяет генерировать такие абстракции на лету, что как раз Вы сам наглядно и продемонстрировали

shty ★★★★★
() автор топика
Ответ на: комментарий от ahonimous

погуглил - кроме библиотек еще и книг хватает, так что нет смысла сравнивать языки, основываясь на доморощенных решениях пользователей с ЛОР

ahonimous
()
Ответ на: комментарий от linuxfan

Я бы решал такую задачу на прологе (возможно, специального вида), реализованного на CL - на CL из-за того что будет возможность использовать макро-средства и в рамках пролога (т.е. очень просто строить генераторы пролога). Ну и PAIP взял как справочник - там всё это есть.

Но мне кажется что семантический анализ текстов и логический солвер это очень разные вещи. Мне кажется что в решении основной задачи (пока не определённой) нужно начать с простых примеров - такой-то текст, будем использовать такую грамматику, нужны распознать такую-то категорию.

quasimoto ★★★★
()
Ответ на: комментарий от shty

>вот нифига, С++, к примеру, не позволяет генерировать такие абстракции на лету, что как раз Вы сам наглядно и продемонстрировали

Абстракция — это не «хрен знает что для всего пригодное», а выражение элемента предметной области задачи в терминах используемого языка разработки. И таких абстракций (сюрприз!) конечное число. Что там C++ не позволил выразить? Отношение «A женат на B» или «C танцует с D»?

Ой, какой ужас: мы перевели условие задачи с естественного языка на язык программирования — нидастатачна абстрактна!!1 :D

linuxfan
()
Ответ на: комментарий от quasimoto

> Я бы решал такую задачу на прологе (возможно, специального вида), реализованного на CL

код бы...

Rastafarra ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.