Prolog收回多个事实,然后断言

Prolog收回多个事实,然后断言,prolog,Prolog,我们每个单位有三个论点。所以公寓(房间、价格、地址的排列) 我想改变这条街上所有公寓的价格 所以当我把changeprice('Nollendorfstr')放在那里时。 这只会改变其中一个。 如何更改它们?您可以使用故障驱动循环(其名称来源于在处理项目后使用显式故障来回溯到处理下一个项目): 或者事实上的标准forall/2元谓词(其中第一个参数可以解释为候选解决方案的生成器,由第二个参数(测试部分)验证): 在这种特殊情况下,两种解决方案是等效的。但请注意,故障驱动循环和forall/2调用

我们每个单位有三个论点。所以
公寓(房间、价格、地址的排列)

我想改变这条街上所有公寓的价格

所以当我把
changeprice('Nollendorfstr')放在那里时。
这只会改变其中一个。
如何更改它们?

您可以使用故障驱动循环(其名称来源于在处理项目后使用显式故障来回溯到处理下一个项目):

或者事实上的标准
forall/2
元谓词(其中第一个参数可以解释为候选解决方案的生成器,由第二个参数(测试部分)验证):

在这种特殊情况下,两种解决方案是等效的。但请注意,故障驱动循环和
forall/2
调用具有不同的语义。故障驱动循环可以掩盖意外故障。但是,如果第二个参数失败,则调用
forall/2
将失败,而不是成功

:- 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)).
changeprice(Street):-
   retract(flat(Rooms,Price,addr(Street,Num))),
   Newprice is Price - (Price / 10),                         
   asserta(flat(Rooms,Newprice,addr(Street,Num))).
changeprice(Street) :-
    retract(flat(Rooms,Price,addr(Street,Num))),
    Newprice is Price - (Price / 10),                      
    asserta(flat(Rooms,Newprice,addr(Street,Num))),
    fail.
changeprice(_).
changeprice(Street) :-
    forall(
        retract(flat(Rooms,Price,addr(Street,Num))),
        (   Newprice is Price - (Price / 10),                      
            asserta(flat(Rooms,Newprice,addr(Street,Num)))
        )
    ).