繁体   English   中英

在 prolog 文件中运行 Prolog 查询并将结果存储在 txt 文件中

[英]Run Prolog queries within prolog file and store the result in a txt file

我有一个 prolog 文件test1.P下面提到,我想在这个文件上测试多个查询,因此我添加了 3 个循环(query1,query2,quer3):我想存储查询的结果和时间查询已对文本文件“result.txt”进行评估。 问题是这段代码工作正常,但它只将最后一次查询的结果存储在文件中,并且不将时间与查询一起存储。

sol(Goal, Pair) :-
   term_variables(Goal, Vars),
   findall(Vars, Goal, Substs),
   write_list_to_file('result.txt',Substs),
   Pair = Vars-Substs.
   
ans(Goal, Pair):- statistics(runtime,[Start|_]),
sol(Goal, Pair),
statistics(runtime,[Stop|_]),
Runtime is Stop - Start,
write(Runtime).

loop_through_list(File, List) :-
    member(Element, List),
    write(File, Element),
    write(File, ' '),
    fail.

write_list_to_file(Filename,List) :-
    open(Filename, write, File),
    \+ loop_through_list(File, List),
    close(File).
    
:- forall(ans((pred1(X,Y),pred2(X,'BaldEagle')),L), writeln(L)). //query1
:- forall(ans((pred1(X,Y), pred3(X,'Eagle')),L), writeln(L1)). //quer2
:- forall(ans((pred1(X,Y), pred4(Y,Z)),L), writeln(L2)). //query3

因此,我没有在test1.P中使用 3 个查询,而是创建了另一个名为testQueries.P的文件,并像这样编写查询:

query(ans((pred1(X,Y),pred2(X,'BaldEagle')),L), writeln(L)).
query(ans((pred1(X,Y), pred3(X,'Eagle')),L), writeln(L1)).
query(ans((pred1(X,Y), pred4(Y,Z)),L), writeln(L2)).

myforall(X,Y) :- \+ (X, \+ Y).
mywrite(T) :- write(T), nl.
mycount(Query, Count) :-
                setof(Query, Query, Set),
                length(Set, Count),
                Count = 0.
test :-
    mycount(query(Q), Count).    
    myforall(query(Q), (Q -> mywrite(yes:Q); mywrite(no:Q))),
    halt.


:- initialization(['test1.P']).
:- initialization(test).

但我仍然无法将所有查询的结果和时间存储在文本文件中。 另外,我如何获得针对查询生成的结果数量?

问题是双重的:

  • 您在没有File作为参数的情况下执行“以毫秒为单位的运行时间”的write(Runtime) 因此,output 转到“标准输出”(或者可能是“当前输出”),即终端,而不是文件。
  • 对于每个查询,您以open(Filename, write, File)的形式打开文件,写下您想写的任何内容,然后关闭文件。 该文件以write模式打开,这实际上是truncation模式:文件被清空,并且在文件 position 0 处重新开始写入。这解释了为什么只看到有关最后一个查询的信息。 您必须在append模式下打开文件: open(Filename, append, File)或在关闭文件之前写下您想要写入的所有内容。

改进的write_list_to_file/3 ,我们使用forall/2而不是“故障驱动循环”:

write_list_to_file(Filename,List,Mode) :-
    must_be(oneof([write,append]),Mode),
    setup_call_cleanup(    
       open(Filename, Mode, File),  % but what's the encoding? It depends!
       forall(
          member(Element,List),
          (
             write(File,Element),
             write(File,' ')
          )
       ),
       close(File)).

因此,必须使用Mode = write调用一次,使用Mode = append调用两次。 但这仍然无助于将运行时毫秒数放入文件中。

代码相当复杂。 也许可以大大简化。

例如,这仍然不理想(特别是因为它反复打开和关闭文件),但使用上面的write_list_to_file/3


question1(X,Y) :-
   pred1(X,Y),
   pred2(X,'BaldEagle')).
   
question2(X,Y) :-
   pred1(X,Y), 
   pred3(X,'Eagle')),

question3(X,Y,Z) :-
   pred1(X,Y),
   pred4(Y,Z).
   
time_goal(Goal,VarsBindings,Delta_ms) :-
   statistics(runtime,[Start|_]),
   term_variables(Goal, Vars),
   findall(Vars,Goal,VarsBindings),
   statistics(runtime,[Stop|_]),  
   Delta_ms is Stop - Start.
   
time_goal(Goal,Filename,Mode) :-
   time_goal(Goal,VarsBindings,Delta_ms),
   write_list_to_file(Filename,[Goal,Delta_ms],Mode),
   write_list_to_file(Filename,VarsBindings,append).

time_all(Filename) :-
   time_goal(question1(X,Y),Filename,write),
   time_goal(question2(X,Y),Filename,append),
   time_goal(question3(X,Y,Z),Filename,append).

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM