具有动态谓词的模块
Modules with dynamic predicates
这是后续问题:
如果我定义了以下模块:
:- module(csv_load_mod,[prepare_db/3]).
:- 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, []).
然后我可以从 csv 文件中读取 table。
例如:
:? prepare_db('my_table.csv',mt_col_key, mt_relation).
然后我会有一个事实 mt_col_key([col1,col2,...,coln])
和一组事实 mt_relation/3
。但是这些对于模块来说是本地的,不会被导出。我需要使用 csv_load_mod:mt_relation/3
等。有没有办法让模块导出动态谓词或适应 prepare_db/3
所以它断言的事实不是本地的,或者它们被断言给调用它的模块?
我简化了应用逻辑,以更好地说明有趣的观点。我们需要 3 样东西:一个模块 'driver',即 test_csv.pl,通用加载器,即 csv_module_test.pl,至少一个文件,即 file.csv
driver:
:- module(test_csv, [test_csv/0]).
:- use_module(csv_module_test).
test_csv :-
context_module(CM),
prepare_db(CM, 'file.csv').
装载机:
:- module(csv_module_test, [prepare_db/2]).
:- use_module(library(csv)).
prepare_db(CM, File) :-
forall(csv_read_file_row(File, Row, []), store_row(CM, Row)).
store_row(CM, Row) :-
Row =.. [row,RelName|Cols],
Record =.. [RelName|Cols],
CM:assertz(Record).
测试数据,file.csv:
key,desc,col1,col2,col3,col4,col5
key_x,desc_x,1,2,3,4,5
key_y,desc_y,10,20,30,40,50
那么,
?- test_csv.
true.
?- test_csv:listing.
:- dynamic rel/3.
test_csv :-
context_module(A),
prepare_db(A, 'file.csv').
:- dynamic key/1.
:- dynamic key_y/6.
key_y(desc_y, 10, 20, 30, 40, 50).
:- dynamic key_x/6.
key_x(desc_x, 1, 2, 3, 4, 5).
:- dynamic key/6.
key(desc, col1, col2, col3, col4, col5).
true.
也就是说,关系已声明为动态关系并在 driver 模块中声明...
注意:关系的名称是假的,因为我开始尝试遵循您的应用逻辑,后来转向简化方法...
这是后续问题:
如果我定义了以下模块:
:- module(csv_load_mod,[prepare_db/3]).
:- 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, []).
然后我可以从 csv 文件中读取 table。
例如:
:? prepare_db('my_table.csv',mt_col_key, mt_relation).
然后我会有一个事实 mt_col_key([col1,col2,...,coln])
和一组事实 mt_relation/3
。但是这些对于模块来说是本地的,不会被导出。我需要使用 csv_load_mod:mt_relation/3
等。有没有办法让模块导出动态谓词或适应 prepare_db/3
所以它断言的事实不是本地的,或者它们被断言给调用它的模块?
我简化了应用逻辑,以更好地说明有趣的观点。我们需要 3 样东西:一个模块 'driver',即 test_csv.pl,通用加载器,即 csv_module_test.pl,至少一个文件,即 file.csv
driver:
:- module(test_csv, [test_csv/0]).
:- use_module(csv_module_test).
test_csv :-
context_module(CM),
prepare_db(CM, 'file.csv').
装载机:
:- module(csv_module_test, [prepare_db/2]).
:- use_module(library(csv)).
prepare_db(CM, File) :-
forall(csv_read_file_row(File, Row, []), store_row(CM, Row)).
store_row(CM, Row) :-
Row =.. [row,RelName|Cols],
Record =.. [RelName|Cols],
CM:assertz(Record).
测试数据,file.csv:
key,desc,col1,col2,col3,col4,col5
key_x,desc_x,1,2,3,4,5
key_y,desc_y,10,20,30,40,50
那么,
?- test_csv.
true.
?- test_csv:listing.
:- dynamic rel/3.
test_csv :-
context_module(A),
prepare_db(A, 'file.csv').
:- dynamic key/1.
:- dynamic key_y/6.
key_y(desc_y, 10, 20, 30, 40, 50).
:- dynamic key_x/6.
key_x(desc_x, 1, 2, 3, 4, 5).
:- dynamic key/6.
key(desc, col1, col2, col3, col4, col5).
true.
也就是说,关系已声明为动态关系并在 driver 模块中声明...
注意:关系的名称是假的,因为我开始尝试遵循您的应用逻辑,后来转向简化方法...