2015-07-22 2 views
1

У меня есть следующие:Адаптация CSV чтение для нескольких таблиц

:- use_module(library(csv)). 
:- dynamic mb/3. 
:- dynamic mb_column_keys/1. 

prepare_db(File) :- 
    retractall(mb_column_keys(_)), 
    retractall(mb(_,_,_)), 
    forall(read_row(File, Row), store_row(Row)). 

store_row(Row) :- 
    Row =.. [row|Cols], 
    ( mb_column_keys(ColKeys) 
    -> Cols = [RowKey|Samples], 
    maplist(store_sample(RowKey), ColKeys, Samples) 
    ; (Cols = [_H|T],assertz(mb_column_keys(T))) 
    ). 

store_sample(RowKey, ColKey, Sample) :- 
    assertz(mb(RowKey, ColKey, Sample)). 

read_row(File, Row) :- 
    csv_read_file_row(File, Row, []), 
    writeln(read_row(Row)). 

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

Например ?-prepare_db('my_file.csv',mb_column_keys,mb).

бы привести факты будучи утверждавших для МБ/3 и mb_column_keys/1

Ok Я изменил файл к следующему, который работает:

:- use_module(library(csv)). 
:- set_prolog_stack(global, limit(4*10**9)). 

prepare_db(File, Column_Key,Relation) :- 
    Column_Key_Term =.. [Column_Key,_], 
    Relation_Term =.. [Relation,_,_,_], 
    retractall(Column_Key_Term), 
    retractall(Relation_Term), 
    forall(read_row(File, Row), store_row(Row,Column_Key,Relation)). 

store_row(Row,Column_Key,Relation) :- 
    Column_Key_Test =.. [Column_Key,ColKeys], 
    Row =.. [row|Cols], 
    ( call(Column_Key_Test) 
    -> Cols = [RowKey|Values], 
     maplist(store_relation(Relation,RowKey), ColKeys, Values) 
     ; (Cols = [_H|T], 
       Column_Key_Term =.. [Column_Key,T], 
       assertz(Column_Key_Term) 
      ) 
    ). 

store_relation(Relation,RowKey, ColKey, Values) :- 
    Relation_Term =.. [Relation,RowKey,ColKey,Values], 
    assertz(Relation_Term). 

read_row(File, Row) :- 
    csv_read_file_row(File, Row, []), 
    writeln(read_row(Row)). 

Но это кажется немного уродливым, есть ли более элегантный способ сделать это?

+0

ok- Я изменил его. – user27815

+0

Вы уверены, что вам нужно? Насколько мне известно, ['retractall/1'] (http://www.swi-prolog.org/pldoc/doc_for?object=retractall/1) объявляет свой аргумент как динамический предикат. –

+2

@Boris: определенно лучше объявить его - включить статический анализ – false

ответ

1

С retractall/1 объявляет свой аргумент как dynamic, вы могли бы передать список предикатных глав в prepare_db, как это:

prepare_db(File, Heads) :- 
    maplist(retractall, Heads), 
    % etc 

?- prepare_db('my_file.csv', [mb_column_keys(_) ,mb(_,_,_)]). 

И имейте в виду, что SWI-Prolog по крайней мере, позволяет назвать dynamic/1:

?- foo(_). 
ERROR: toplevel: Undefined procedure: foo/1 (DWIM could not correct goal) 
?- dynamic(foo/1). 
true. 

?- foo(_). 
false. 

(вы увидите это возможно, если вы читаете между строками сноски к документации retractall/1 ...)

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

Смежные вопросы