[英]How to run prolog queries from within the prolog file in swi-prolog?
[英]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.