Prolog收回了一个以上的事实然后断言

时间:2018-06-03 13:06:08

标签: 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'). 它只会改变其中一个。 我怎样才能改变所有这些?

1 个答案:

答案 0 :(得分:0)

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

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调用将失败而不是成功。