代码之家  ›  专栏  ›  技术社区  ›  user27815

带有动态谓词的模块

  •  2
  • user27815  · 技术社区  · 9 年前

    这是一个后续问题: Adapting csv reading for multiple tables

    如果我定义了以下模块:

    :- 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文件中读取表格。

    例如:

    :? 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 所以它断言的事实不是本地的,或者它们被断言给调用它的模块?

    1 回复  |  直到 5 年前
        1
  •  2
  •   CapelliC    9 年前

    我简化了应用逻辑,以更好地说明有趣的点。我们需要三件事:一个模块“driver”,即test_csv。pl,通用加载器,即csv_module_test。pl和至少一个文件,即file.csv

    驾驶员:

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

    测试数据,文件.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.
    

    也就是说,关系已声明为动态的,并在驱动程序模块中声明。。。

    注意:关系的名称是假的,因为我一开始试图遵循你的应用逻辑,后来转向了一种简化的方法。。。