使用序言格式谓词打印到文件
Using the prolog format predicate to print to file
是否可以使用 prolog format
谓词打印到文件?
我有一个 table 数据,我使用格式谓词打印到标准输出,即
print_table :-
print_table_header,
forall(range(1.0,10.0,0.1,N), print_row(N,L)).
%% print_row(L) :- take a list of the form, [a,b,c,d,e] and
%% print it to screen as a single row of tab separated float values (1DP)
print_row(N,L) :-
build_row(N,L),
format('~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~n', L).
print_table_header :-
format('~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~n', ['N','N2','N3','N4','N5']).
最好能以某种方式重用代码以将相同的内容打印到文件中。
你可以!
考虑 SICStus Prolog documentation for format/[2,3]
的以下摘录:
11.3.85 format/[2,3]
Synopsis
format(+Control, +Arguments)
format(+Stream, +Control, +Arguments)
Interprets the Arguments according to the Control string and prints the result on Stream.
谓词 format/[2,3]
在 Prolog 实现中得到广泛支持。
但是,截至目前,这些谓词还不是 ISO Prolog 的一部分。
我会用一个附加参数 Stream
编写输出 'routines',然后我会在测试或打印到屏幕时传递 user
。请参阅 ISO 谓词 open/3、close/1 等以进行流处理...
请注意,IO 它是语言中最少 'declarative' 的领域之一,因为为了提高效率,需要一种基于副作用的方法...
SWI-Prolog 有一个内置的with_output_to, that would allows to reuse your existing code without adding a parameter. But since you tagged iso-prolog你的问题,你真的应该添加 Stream 参数...
除了另一个好的答案(+1!)之外,我想为此类任务提供一个更纯粹的解决方案。
关键思想是让 format/2
在 DCG 中可访问,然后使用 DCG 来描述输出。
这非常简单,使用 format/3
的 codes
参数,由多个 Prolog 实现提供。您只需要以下简短的辅助定义:
format_(Data, Args) --> call(format_dlist(Data, Args)).
format_dlist(Data, Args, Cs0, Cs) :- format(codes(Cs0,Cs), Data, Args).
非终结符 call//1
使用两个附加参数调用其参数,使您可以访问隐式 DCG 参数,这用于通过 format/3
.
描述附加代码
现在,我们可以简单地在 DCG 中使用非终结符 format_//2
。
例如描述一个简单的table:
table -->
row([a,b,c]),
row([d,e,f]).
row(Ls) --> format_("~t~w~10+~t~w~10+~t~w~10+~n", Ls).
使用示例和结果:
?- phrase(table, Cs), format("~s", [Cs]).
a b c
d e f
Cs = [32, 32, 32, 32, 32, 32, 32, 32, 32|...].
请注意,最后剩下的 format/2
用于实际将输出写入屏幕。
但是,其他一切都没有副作用,并且声明性地描述了一个 table。
此方法的一个重要优点是您可以轻松编写 测试用例 以查看您的 table 是否(仍然)正确格式化。推导 Prolog 代码列表(用 DCG 描述)很容易,但推导只出现在终端上的东西却很困难。
是否可以使用 prolog format
谓词打印到文件?
我有一个 table 数据,我使用格式谓词打印到标准输出,即
print_table :-
print_table_header,
forall(range(1.0,10.0,0.1,N), print_row(N,L)).
%% print_row(L) :- take a list of the form, [a,b,c,d,e] and
%% print it to screen as a single row of tab separated float values (1DP)
print_row(N,L) :-
build_row(N,L),
format('~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~n', L).
print_table_header :-
format('~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~n', ['N','N2','N3','N4','N5']).
最好能以某种方式重用代码以将相同的内容打印到文件中。
你可以!
考虑 SICStus Prolog documentation for format/[2,3]
的以下摘录:
11.3.85 format/[2,3]
Synopsis
format(+Control, +Arguments)
format(+Stream, +Control, +Arguments)
Interprets the Arguments according to the Control string and prints the result on Stream.
谓词 format/[2,3]
在 Prolog 实现中得到广泛支持。
但是,截至目前,这些谓词还不是 ISO Prolog 的一部分。
我会用一个附加参数 Stream
编写输出 'routines',然后我会在测试或打印到屏幕时传递 user
。请参阅 ISO 谓词 open/3、close/1 等以进行流处理...
请注意,IO 它是语言中最少 'declarative' 的领域之一,因为为了提高效率,需要一种基于副作用的方法...
SWI-Prolog 有一个内置的with_output_to, that would allows to reuse your existing code without adding a parameter. But since you tagged iso-prolog你的问题,你真的应该添加 Stream 参数...
除了另一个好的答案(+1!)之外,我想为此类任务提供一个更纯粹的解决方案。
关键思想是让 format/2
在 DCG 中可访问,然后使用 DCG 来描述输出。
这非常简单,使用 format/3
的 codes
参数,由多个 Prolog 实现提供。您只需要以下简短的辅助定义:
format_(Data, Args) --> call(format_dlist(Data, Args)).
format_dlist(Data, Args, Cs0, Cs) :- format(codes(Cs0,Cs), Data, Args).
非终结符 call//1
使用两个附加参数调用其参数,使您可以访问隐式 DCG 参数,这用于通过 format/3
.
现在,我们可以简单地在 DCG 中使用非终结符 format_//2
。
例如描述一个简单的table:
table -->
row([a,b,c]),
row([d,e,f]).
row(Ls) --> format_("~t~w~10+~t~w~10+~t~w~10+~n", Ls).
使用示例和结果:
?- phrase(table, Cs), format("~s", [Cs]).
a b c
d e f
Cs = [32, 32, 32, 32, 32, 32, 32, 32, 32|...].
请注意,最后剩下的 format/2
用于实际将输出写入屏幕。
但是,其他一切都没有副作用,并且声明性地描述了一个 table。
此方法的一个重要优点是您可以轻松编写 测试用例 以查看您的 table 是否(仍然)正确格式化。推导 Prolog 代码列表(用 DCG 描述)很容易,但推导只出现在终端上的东西却很困难。