Есть ли какие-то конкретные правила преобразования данных MySQL в правила Prolog для исследовательского майнинга?

У меня есть три таблицы (на данный момент), одна с 2000 строками, а две другие - примерно с 1,6 миллиона строк каждая. У них есть столбцы, которые связывают их друг с другом, но они не являются формальными полями FK. Я написал программу на C ++ для создания файлов правил на основе исходных данных MySQL, например:

if T{ C1, C2...Cn } is the table definition
then the rule would be:
    T(C1, C2, Cn).

Моя утилита преобразования оставляет целые числа развернутыми, а все остальное помещается в одинарные кавычки, поэтому INT (n), DECIMAL и т. Д. Становятся числами Пролога, а все остальное является атомом.

Тогда мой вопрос таков: если я хочу написать правило поиска для таблицы / правила с 26 полями, существует ли способ "мета-уровня" выразить это:

findStuffById(I,FieldIWant1,FieldIwant2etc) :-
    tablename(_,_,I,_,FieldIWant1,_,_,_FieldIWant2etc,_,_,....).

Или мне нужно создать «более простые» правила, которые затем должны будут использовать «_» или переменные для захвата того, что я хочу?

Перспектива написания правил вроде ...

findThisById(X)     :- tablename(X,_,_,_,_,This,_,_).
findThatById(X)     :- tablename(X,_,_,That,_,_,_,_).
findTheOtherById(X) :- tablename(X,_,_,_,_,_,_,TheOther).

... до тошноты ... тревожит!

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

Я предполагаю, что моя программа преобразования может также кодировать, генерируя правила drudge, так что мне не придется вручную кодировать это. В больших таблицах 26 и 28 столбцов в каждой, так что вы можете видеть, к чему это идет!

Любые советы о том, как действовать, будут приветствоваться; У меня нет возможности использовать Prolog так много, как хотелось бы, и я всегда хочу узнать больше!

Я хочу создать веб-сервер SWI-Prolog, который будет сражаться лицом к лицу с сервером ElasticSearch, используя те же необработанные данные, чтобы узнать, какой из них быстрее всего отвечает на специальные запросы. Похоже, что ES не выполняет и традиционных соединений, если вы заранее не создаете составной документ со встроенными индексами, что также может быть в пользу использования Prolog.

Спасибо. Шон.


person Emacs The Viking    schedule 13.06.2013    source источник


Ответы (2)


Вы могли бы использовать nth1/1 и оператор univ, сделав что-то вроде этого:

fieldnames(t, [id,this,that]).
get_field(Field, Tuple, Value) :- 
    Tuple =.. [Table|Fields],
    fieldnames(Table, Names),
    nth1(Idx, Names, Field),
    nth1(Idx, Fields, Value).

Вам нужно будет создать fieldnames/2 записи для каждой структуры таблицы, и вам нужно будет передать структуру таблицы вместе с этим запросом. Это было бы не очень эффективно, но сработало бы.

?- get_field(this, t(testId, testThis, testThat), Value)
Value = testThis

Затем вы можете довольно легко построить свои аксессуары поверх этого:

findThisById(X, This) :- get_field(this, X, This).

Изменить: Борис справедливо отмечает, что arg/3 сделает это с еще меньшими усилиями:

get_field(Field, Tuple, Value) :-
    functor(Tuple, Table, _),
    fieldnames(Table, Names),
    nth1(Idx, Names, Field),
    arg(Idx, Tuple, Value).

Пролог такой классный.

person Daniel Lyons    schedule 13.06.2013
comment
Дэниел, это пища для размышлений. Я знаю об операторе univ и nth / 1 ... Мне тоже нравится идея fieldnames / 2. Я тоже могу понять, почему это не было бы слишком эффективно, но это сделано для обнаружения, а не производительности, поэтому я надеюсь, что это не имеет большого значения. В любом случае, это все экспериментально! Я подожду, чтобы посмотреть, что еще здесь появится, прежде чем отмечать что-нибудь, кроме как хорошо сделанного, будучи FRIST, как они говорят;) - person Emacs The Viking; 13.06.2013
comment
Дэниел, почему бы не arg/3 непосредственно на функторе (кортеже)? - person ; 13.06.2013
comment
Принял ответ Дэниела, так как у меня было время подумать, и в целом освещение было хорошим источником руководства и в значительной степени тем, чем я был после Спасибо, Дэниел. - person Emacs The Viking; 17.06.2013

В реальной базе данных электронной коммерции я использовал такой код, как

update_price(File, Pid, Cn, Manu) :-
    product(Pid, [tax_class_id = Tid, /*cost = Cost,*/ price = CurrPrice]),
    tax_rate(_, [tax_class_id = Tid, rate = R]),
    manufacturer(Manu, name = NameM),
    (   ( NameM == 'Gruppo Aboca' ; NameM == 'L\'Amande' )
        ->  % Pr is Cost * 3 / 2
        togli_iva(R, Cn, Pr)
    ;   togli_iva(R, Cn, NoIva),
        Pr is NoIva * 2
    ),
    Delta is abs(CurrPrice - Pr),
    (   Delta > 0.01
    ->  Prx is round(Pr * 100) / 100,
        format(File, 'update product set price=~w where product_id=~d~@', [Prx, Pid, eol])
    ;   true
    ).

product, tax_rate, Manufacturer - фактические названия таблиц с известной структурой. Например, у товара 26 столбцов, у tax_rate - 8, ....

У меня есть декларации

:- dynamic 
    ...
    product/2,product/26,
    ...
    tax_rate/2,tax_rate/8,
    ...

Данные считываются из дампа SQL, и когда они сохраняются в памяти, я создаю аксессор product / 2, который заботится о преобразовании полей от имени к положению.

Я не предлагаю использовать этот подход, потому что он будет слишком медленным для ваших данных. Вместо этого вы можете использовать goal_expansion / 2 и переводить - во время компиляции - любой вызов таблицы (field1 = Value1, field2 = Value2) к соответствующему вызову таблицы (,, Value1, _, Value2) - позиционный путь Prolog.

Это должно обеспечить максимальную производительность индексации SWI-Prolog, недавно обновленной для работы со всеми столбцами.

Конечно, чтобы получить более подробную информацию, вы должны опубликовать свой формат метаданных ...

edit: если вас интересуют простые средства доступа к отдельным полям (как я понимаю из комментариев к ответу Даниэля), вы можете попробовать библиотеку (запись) .

person CapelliC    schedule 13.06.2013