如何在prolog中加入规则并打印输出
我有如下事实清单如何在prolog中加入规则并打印输出,prolog,Prolog,我有如下事实清单 items(itemId('P01'),prodName('Pots'),stockQty(50),price(8200)). items(itemId('P02'),prodName('Pans'),stockQty(50),price(400)). items(itemId('P03'),prodName('Spoons'),stockQty(50),price(200)). items(itemId('P04'),prodName('Forks'),stockQty(50
items(itemId('P01'),prodName('Pots'),stockQty(50),price(8200)).
items(itemId('P02'),prodName('Pans'),stockQty(50),price(400)).
items(itemId('P03'),prodName('Spoons'),stockQty(50),price(200)).
items(itemId('P04'),prodName('Forks'),stockQty(50),price(120)).
items(itemId('P05'),prodName('Kettles'),stockQty(50),price(500)).
items(itemId('P06'),prodName('Plates'),stockQty(50),price(60)).
当发出print\u all\u products.
等命令时,如何在控制台上打印以下内容
可用产品
名称数量
盆60
平底锅50
汤匙40
- 名称和数量必须在表格结构中正确格式化
forall
和foreach
生成所需的内容,但未成功。。。。要将内容放在整齐的列中,请使用~
,~t
,~+
~
将选项卡设置为“此处”,~t
插入填充字符,~+
将选项卡前进到最后一个“此处”(~
)之外,并分发填充字符。所以
format("(~|~`.t~d~5+)~n", [123])
生成
(…123)
——格式字符串用宽度为5的
s右对齐数字,并用括号括起来。您要求的是SQL样式的表格输出,是的,从Reagan是prez时起,该语言就应该是基本谓词集。我不知道发生了什么事。它可能在图书馆里(但图书馆在哪里?)
同时,这里是“故障驱动循环”,使用了我个人工具箱中的一些好东西,但它使用了SWI Prolog:
在文件printThemes.pl
中:
:- use_module(library('heavycarbon/strings/string_of_spaces.pl')).
:- use_module(library('heavycarbon/strings/string_overwriting.pl')).
items(itemId('P01'),prodName('Pots'),stockOty(50),price(8200)).
items(itemId('P02'),prodName('Pans'),stockOty(50),price(400)).
items(itemId('P03'),prodName('Spoons'),stockOty(50),price(200)).
items(itemId('P04'),prodName('Forks'),stockOty(50),price(120)).
items(itemId('P05'),prodName('Kettles'),stockOty(50),price(500)).
items(itemId('P06'),prodName('Plates'),stockOty(50),price(60)).
printthem :-
% ideally these should be built by getting max(length) over a column - hardcode for now!
string_of_spaces(5,SpacesId),
string_of_spaces(10,SpacesName),
string_of_spaces(4,SpacesQuant),
string_of_spaces(6,SpacesPrice),
% begin failure-driven loop!
items(itemId(Id),prodName(Name),stockOty(Quant),price(Price)), % backtrack over this until no more solutions
% transform data into string; see predicate format/2;
% capture output instead of letting it escape to STDOUT
with_output_to(string(TxtId),format("~q",[Id])),
with_output_to(string(TxtName),format("~q",[Name])),
with_output_to(string(TxtQuant),format("~d",[Quant])),
with_output_to(string(TxtPrice),format("~d",[Price])),
% formatting consist in overwriting the space string with the data-carrying string
string_overwriting(SpacesId,TxtId, 1,TxtIdFinal),
string_overwriting(SpacesName,TxtName, 1,TxtNameFinal),
string_overwriting(SpacesQuant,TxtQuant, 1,TxtQuantFinal),
string_overwriting(SpacesPrice,TxtPrice, 1,TxtPriceFinal),
% output the line
format("~s~s~s~s\n",[TxtIdFinal,TxtNameFinal,TxtQuantFinal,TxtPriceFinal]),
% close the loop
fail.
以上只是一个简单的例子。可以从几个不同的方向进行改进
模块通过以下方式加载:
:- use_module(library('heavycarbon/strings/string_of_spaces.pl')).
:- use_module(library('heavycarbon/strings/string_overwriting.pl')).
可从GitHub获得。你将不得不抓取几个文件,并适当地安排它们。读剧本。不要介意乱七八糟,这是正在进行的工作
如果所有设置都正确:
?- [printthem].
true.
?- printthem.
'P01' 'Pots' 50 8200
'P02' 'Pans' 50 400
'P03' 'Spoons' 50 200
'P04' 'Forks' 50 120
'P05' 'Kettles' 50 500
'P06' 'Plates' 50 60
false.
更多细节的答案已发布。 下面是代码,所以这不是一个链接唯一的答案
items(itemId('P01'),prodName('Pots'),stockOty(50),price(8200)).
items(itemId('P02'),prodName('Pans'),stockOty(50),price(400)).
items(itemId('P03'),prodName('Spoons'),stockOty(50),price(200)).
items(itemId('P04'),prodName('Forks'),stockOty(50),price(120)).
items(itemId('P05'),prodName('Kettles'),stockOty(50),price(500)).
items(itemId('P06'),prodName('Plates'),stockOty(50),price(60)).
header("\n........................\nAvailable Products\n........................\nName Qty\n").
footer("........................\n").
spaces(Length,Spaces) :-
length(List,Length),
maplist([_,0'\s]>>true,List,Codes),
string_codes(Spaces,Codes).
padded_string(String,Width,Padded_string) :-
string_length(String,String_length),
Padding_length is Width - String_length,
spaces(Padding_length,Padding),
atom_concat(String,Padding,Padded_string).
format_detail_line(item(Name,Quantity),width(Name_width),Formatted_item) :-
padded_string(Name,Name_width,Padded_name),
atom_concat(Padded_name,Quantity,Formatted_item).
add_detail_line(width(Name_Width),Item,Lines0,Lines) :-
format_detail_line(Item,width(Name_Width),Formatted_item),
atomic_list_concat([Lines0,Formatted_item,"\n"], Lines).
items_detail(Detail) :-
findall(item(Name,Quantity),items(_,prodName(Name),stockOty(Quantity),_),Items),
aggregate_all(max(Width),Width,(items(_,prodName(Name),_,_),string_length(Name,Width)),Name_Width),
Name_field_width is Name_Width + 1,
foldl(add_detail_line(width(Name_field_width)),Items,"",Detail).
print_all_products(Report) :-
header(Header),
items_detail(Detail),
footer(Footer),
atomic_list_concat([Header,Detail,Footer], Report).
print_all_products :-
print_all_products(Report),
write(Report).
:- begin_tests(formatted_report).
test(1) :-
print_all_products(Report),
with_output_to(atom(Atom),write(Report)),
assertion( Atom == '\n........................\nAvailable Products\n........................\nName Qty\nPots 50\nPans 50\nSpoons 50\nForks 50\nKettles 50\nPlates 50\n........................\n' ).
:- end_tests(formatted_report).
注:Peter给出的格式是进行格式化的惯用方法,但正如我所指出的,这让我发疯。即便如此,这也是我在生产环境中的做法 我给出这个答案是因为OP注意到他们正在寻找一种使用forall/2或foreach/2等谓词的方法。虽然这两种方法均未在本答案中使用,但使用了更实用的方法
如果问题更加开放,我会使用DCGs给出答案。在其他编程语言中,打印类似于业务报告的数据是常见的,您的输出类似于业务报告。在Prolog中,我很少将输出格式化为业务报告,因为这不是我使用Prolog的原因。如果您正试图学习Prolog,那么就要学习如何使用Prolog,因为这是您所知道的。将您的思想从其他编程语言的概念中解放出来,从头开始学习Prolog。继续。换句话说,如果你让它变得困难的话,学会在Prolog上做得很棒并不容易。如果你想让学习Prolog变得更加困难,那么试着从一开始就学会错误地使用Prolog,然后花上数倍的努力来忘记错误的使用Prolog的方法,从而在Prolog上取得好成绩。哦,好的。除了类似报告的结构之外,学习如何打印出所有可用值的列表不是很好吗?@GuyCoder你能检查一下吗。我已经简化了这个问题。使用格式为/2的
~t
,~
和~+
使我发疯。@GuyCoder我也是~
将选项卡设置为“here”,~t
插入填充字符,~+
将选项卡推进到最后一个“here”(~
)之后,并分配填充字符。因此,格式('(~~~`.t~d~5+~n',[123])
产生(…123)
。。。这个数字用宽度为5的
s右对齐。您能否添加更多真实世界的示例,并在SWI Prolog论坛上创建一个Wiki?:)“我会的,但我可能会发疯。”GuyCoder——我在回答中加入了我的真实世界的例子;如果你愿意,你可以投上一票同时,我的单元测试显示SWI Prolog在8.3.4和8.3.5之间获得了额外的不确定性。有趣的。。。说到里根,我注意到这本关于“战略防御计划”计算方面的书只提到了一次Prolog,甚至没有一次出现在索引中,而LISP在每一页上都会被提到两次。只关心本地区的好的,继续工作。您不需要字符串\u空格
。。。只需使用格式
(参见我的答案)<代码>格式还可以很容易地对项目进行右对齐。@GuyCoder Jeez有时人们只想在10分钟内完成事情。@GuyCoder经过30年的开发,我看到了很多。这就是为什么我们有一个包含10000个条目的表来测试Casesty it,它能工作吗?