1

我有以下内容:

:- 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 和 mb 的谓词。

例如?-prepare_db('my_file.csv',mb_column_keys,mb).

将导致事实被断言为 mb/3 和 mb_column_keys/1

好的,我已将文件更改为以下内容:

:- 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)).

但它确实看起来有点难看,有没有更优雅的方法来完成这个?

4

1 回答 1

1

由于retractall/1将其参数声明为 a dynamic,您可以将谓词 Heads 列表传递给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

正如您在问题下所说的那样,有理由说明您仍然可以声明您的动态谓词。

于 2015-07-22T11:46:03.330 回答