DCG文件输出 [英] DCG for file output
问题描述
男(bob)。
男(戴夫)。
男(fred)。
男(dereck)。
喜欢(bob,蛋糕)。
喜欢(鲍勃,馅饼)。
喜欢(鲍勃,苹果)。
喜欢(戴夫,鱼)。
喜欢(戴夫,肉)。
喜欢(戴夫,土豆)。
喜欢(戴夫,梨)。
喜欢(fred,水)。
喜欢(fred,啤酒)。
喜欢(dereck,wine)。
喜欢(dereck,蛋糕)。
打印: -
forall(
男性(人),
(
格式(〜w (人物),
格式(〜w,[物品])
),
格式(〜n〜n,[])
)
)。
输出是:
<$ p
$ b $
$ b dereck,wine,cake,%<我不要这些最后的逗号
person_likes(Who,Whats) - >
atom(Who),atom(':'),
likes_(Whats)。
likes _([]) - > [新队]。
likes _([X]) - >原子(X),[换行符]。
likes _([X,Y | Rest]) - > atom(X),atom(','),likes _([Y | Rest])。
atom(A) - > [原子(A)]。
正如您所看到的,主要想法是根据列表中元素的数量。这就说明了如何解决这个问题。
您可以像这样使用它:
<$ p $ (人物喜欢(bob,[cake,pie]),Instrs)。
Instrs = [atom(bob),atom(':'),atom(cake),atom(','),atom(pie),newline]。
对于所需的输出,只需解释这些格式化指令即可。例如:
输出(换行符): - nl。
输出(原子(A)): - 格式(〜w,[A])。
示例查询,以您的示例事实为例:
< (M,W),什么),
短语(person_likes(M,Whats),Ts),
maplist(output,Ts),false。
收益率:
< code bob:蛋糕,馅饼,苹果
dave:鱼,肉,土豆,梨
fred:水,啤酒
dereck:酒,蛋糕
当然,在这个具体情况下,您可以使用相同的模式来获得更短,不纯的版本(使用副作用)。但是你不能在另一个方向使用它!所以,研究纯文本是值得的。
If I have a program like this and I want the last item for a person not to have a comma following it, how do I do this? Is it best to use a DCG? How would that work?
male(bob).
male(dave).
male(fred).
male(dereck).
likes(bob,cake).
likes(bob, pie).
likes(bob, apple).
likes(dave, fish).
likes(dave, meat).
likes(dave, potato).
likes(dave, pear).
likes(fred, water).
likes(fred, beer).
likes(dereck, wine).
likes(dereck, cake).
print:-
forall(
male(Person),
(
format("~w, ",[Person]),
forall(
likes(Person,Item),
format("~w, ",[Item])
),
format("~n~n",[])
)
).
The out put is:
bob, cake, pie, apple,
dave, fish, meat, potato, pear,
fred, water, beer,
dereck, wine, cake, %<I dont want these last commas
Consider first a pure solution, using DCGs to translate a list of things a person likes to a list of formatting instructions that can later be interpreted:
person_likes(Who, Whats) -->
atom(Who), atom(': '),
likes_(Whats).
likes_([]) --> [newline].
likes_([X]) --> atom(X), [newline].
likes_([X,Y|Rest]) --> atom(X), atom(', '), likes_([Y|Rest]).
atom(A) --> [atom(A)].
As you see, the key idea is to distinguish the cases depending on the number of elements in the list. This shows you how to solve such problems very generally.
You can already use it like this:
?- phrase(person_likes(bob, [cake,pie]), Instrs).
Instrs = [atom(bob), atom(': '), atom(cake), atom(', '), atom(pie), newline].
For the desired output, you simply interpret these formatting instructions. For example:
output(newline) :- nl.
output(atom(A)) :- format("~w", [A]).
Sample query, with your example facts:
?- male(M), findall(W, likes(M,W), Whats),
phrase(person_likes(M,Whats), Ts),
maplist(output, Ts), false.
Yielding:
bob: cake, pie, apple
dave: fish, meat, potato, pear
fred: water, beer
dereck: wine, cake
Of course, you can use the same pattern to obtain a shorter, impure version (using side-effects) in this concrete case. But you then cannot use it in the other direction! So, it is worthwhile to study the pure version.
这篇关于DCG文件输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!