我有一个术语包含在文件中:
fruit(apple, []).
我正在尝试向其输入输入,以便每组信息将作为列表附加到空列表以组成列表列表,其方式如下:
fruit(apple, [[30, 'fresh'], [10, 'old'], ... ]).
到目前为止,我只知道如何写一个单独的术语:
add_fruit(File, Type, Price, State) :-
open(File, append, Stream),
writeq(Stream, fruit(Type, [Price, State])),
write(Stream, '.'),
nl(Stream), nl(Stream),
close(Stream).
这将产生一个术语,例如:
fruit(apple, [20, 'some state']).
但是,我不希望每次使用add_fruit
谓词时都必须创建一个新术语,而是希望将包含Price
和State
的列表附加到相应的列表中水果类术语。
是否可以扩展谓词以便它将写入现有术语,而不是创建新术语?
答案 0 :(得分:0)
你在这里混淆了一些概念。首先,如果您有Prolog文件,请说" food.pl"内容:
fruit(apple, []).
然后fruit/2
并不是一个术语,而是事实 fruit/2
(没有正文的谓词,只有头部)映射原子{{1} (第一个参数)到空列表(第二个参数)。
你现在可以做的是查阅文件,这将把事实放在数据库中。
另一件事:您确定需要继续追加第二个参数中的列表吗?为什么不规范化您的数据库,例如:
apple
在这里,您现在有一个表fruit(apple, price_state(30, fresh)).
fruit(apple, price_state(10, old)).
% etc
,有两列。第一个是水果的名称,第二个是 term fruit
,其中第一个参数的价格和第二个参数的状态。你也可以说:
price_state/2
如果你确实希望你的桌子将水果映射到州和价格。您现在可以使用fruit_price_state(apple, 30, fresh).
fruit_price_state(apple, 10, old).
% etc
和assertz
在表格中添加和删除行。换句话说,就像设计关系数据库一样设计数据库,使用事实作为表。这种方法直接转化为Prolog。然后,您可以查询数据库,例如,为您提供苹果价格和状态的组合:
retract
这会在?- bagof(price_state(P, S), fruit(apple, P, S), PSs).
中列出price_state/2
,如果您的数据库中没有苹果,则会失败(如果您愿意,可以使用PSs
而是一个空列表,但是你必须在任何带findall/3
)的谓词中处理那个空列表。
处理持久性的一种方法,即将事实加载到数据库,添加/删除行,然后将更新的数据库保存回同一文件,使用带有PSs
的爱丁堡式I / O, see
,tell
等。
如果您使用的是SWI-Prolog,您还可以选择使用library(persistency)
。请参阅链接以获取有用的最小示例。