【问题标题】:Prolog importing facts from a formatted text fileProlog 从格式化的文本文件中导入事实
【发布时间】:2013-04-13 23:02:00
【问题描述】:

我在文本文件 input.txt 中有以下输入

atom1,atom2,atom3
relation(atom1  ,[10,5,2])
relation(atom2  ,[3,10,2])
relation(atom3  ,[6,5,10])

第一行包括文件中关系谓词中使用的原子列表,剩余的每一行代表一个关系谓词,按照第一行的顺序 list.relation(atom1, [x,y,z]) 表示 atom1 有一个关系第一个原子为 10,第二个原子为 5,第三个原子为 2 我需要阅读这个文件并分别为每个原子添加表示关系值。例如,这些是将为 atom1 添加的关系值:

assert(relation(atom1, atom1,10)).
assert(relation(atom1, atom2, 5)).
assert(relation(atom1, atom3, 2)). 

我已经阅读了一些 prolog io 教程并看到了一些关于使用 DCG 的建议,但我是一个初学者 prolog 程序员,在选择解决问题的方法时遇到了麻烦。所以我在这里向有经验的 prolog 程序员寻求帮助。

【问题讨论】:

    标签: io prolog


    【解决方案1】:

    由于您没有说明您使用的是什么 Prolog,所以这里是一个用 SWI-Prolog 编写的 sn-p。我试图通过 SWI-Prolog 文档参考来表示 ISO 内置函数。

    parse_input :-
        open('input.txt', read, S),
        parse_line(S, atoms(Atoms)),
        repeat,
        (  parse_line(S, a_struct(relation(A, L)))
        -> store(Atoms, A, L), fail
        ;  true ),
        close(S).
    
    :- meta_predicate(parse_line(+, //)).
    
    parse_line(S, Grammar) :-
        % see http://www.swi-prolog.org/pldoc/doc_for?object=read_line_to_codes/2
        read_line_to_codes(S, L),
        L \= end_of_file,
        phrase(Grammar, L).
    
    % match any sequence
    % note - clauses order is mandatory
    star([]) --> [].
    star([C|Cs]) --> [C], star(Cs).
    
    % --- DCGs ---
    
    % comma sep atoms
    atoms(R) -->
        star(S),
        (   ",",
            {atom_codes(A, S), R = [A|As]},
            atoms(As)
        ;   {atom_codes(A, S), R = [A]}
        ).
    
    % parse a struct X,
    % but it's far easier to use a builtin :)
    % see http://www.swi-prolog.org/pldoc/doc_for?object=atom_to_term/3
    a_struct(X, Cs, []) :-
        atom_codes(A, Cs),
        atom_to_term(A, X, []).
    
    % storage handler
    :- dynamic(relation/3).
    
    store(Atoms, A, L) :-
        nth1(I, L, W),
        nth1(I, Atoms, B),
        assertz(relation(A, B, W)).
    

    使用示例 input.txt,我得到

    ?- parse_input.
    true .
    
    ?- listing(relation).
    :- dynamic relation/3.
    
    relation(atom1, atom1, 10).
    relation(atom1, atom2, 5).
    relation(atom1, atom3, 2).
    relation(atom2, atom1, 3).
    relation(atom2, atom2, 10).
    relation(atom2, atom3, 2).
    relation(atom3, atom1, 6).
    relation(atom3, atom2, 5).
    relation(atom3, atom3, 10).
    

    HTH

    【讨论】:

    • 我正在使用 swi-prolog。所以,那太适合了!非常感谢!
    • 但是使用 assertz 而不是 assert 会产生什么不同吗?
    • 不,assertz/1 与 assert/1 相同。或者更好的是,它是官方 (ISO) 接受的名称。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    相关资源
    最近更新 更多