[英]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.