prolog - Prolog收回不止一个事实,然后断言
问题描述
:- dynamic flat/3.
addr('Nollendorfstr',5).
addr('Nollendorfstr',14).
addr('Nollendorfstr',18).
addr('Maxplanckstr',2).
flat([16,12,4],400.35, addr('Nollendorfstr',14)).
flat([14,13,4],380.00, addr('Nollendorfstr',18)).
flat([20,18,4,5],650.80, addr('Nollendorfstr',5)).
flat([9,17,19,20],870.70, addr('Maxplanckstr',2)).
对于每个平面,我们有三个参数。所以flat(array of rooms, price, address)
。
changeprice(Street):-
retract(flat(Rooms,Price,addr(Street,Num))),
Newprice is Price - (Price / 10),
asserta(flat(Rooms,Newprice,addr(Street,Num))).
我想更改这条街上所有公寓的价格。
所以当我把它放在那里时,changeprice('Nollendorfstr').
它只会改变其中一个。我怎样才能改变所有这些?
解决方案
您可以使用失败驱动的循环(它的名称来自在处理一个项目后使用显式失败以回溯到处理下一个项目):
changeprice(Street) :-
retract(flat(Rooms,Price,addr(Street,Num))),
Newprice is Price - (Price / 10),
asserta(flat(Rooms,Newprice,addr(Street,Num))),
fail.
changeprice(_).
或事实上的标准forall/2
元谓词(其中第一个参数可以解释为由第二个参数验证的候选解决方案的生成器,测试部分):
changeprice(Street) :-
forall(
retract(flat(Rooms,Price,addr(Street,Num))),
( Newprice is Price - (Price / 10),
asserta(flat(Rooms,Newprice,addr(Street,Num)))
)
).
在这种特殊情况下,两种解决方案都是等效的。但请注意,失败驱动的循环和forall/2
调用具有不同的语义。故障驱动的循环可以掩盖意外故障。但是forall/2
如果第二个参数失败,调用将失败而不是成功。
推荐阅读
- java - Java 动态绑定失败
- dynamics-crm - 在 Dynamics 365 9.0 上将 PSA 升级到 2.4.x
- python - print(x) TypeError: 'str' 对象不可调用
- c# - Unity Package Manager 窗口在 2018.2 中不可用。?
- python - Scrapy 中间件返回响应
- angularjs - Angular-DataTables:通过使用 Promise 渲染 + 角度绑定 + 行索引 + groupBy 来提高性能
- vue.js - @vue/cli 使用我的库构建应用程序失败
- powerbi - 比较列值与另一个表中的度量(散点图突出显示)
- bash - 使用一个 bash 命令删除多个 rpm 包
- java - ListView 项目中有多个可点击区域?