错误:无权修改静态过程

时间:2018-03-30 13:19:31

标签: prolog

我存储了这样的事实:

 %           name,              price , range
 processor('Intel Core i3 8100', 104, 'low_range').
 motherboard('Asrock B350m', 65, 'low_range').
 ram('Ballistix Sport 4GB 2666mhz', 50, 'low_range').
 case('Sharkoon s25-s', 40, 'low_range').
 ali('Cougar VTX 450w', 43, 'low_range').
 video_card('Nvidia GTX1050 2GB', 130, 'middle_range').
 ssd('Adata SP580 120GB', 40, 'low_range').
 monitor('Asus VC239H Monitor 23"', 163, 'middle_range').
 hdd('Toshiba 1TB 7200rpm', 32, 'middle_range').

我试图根据这些事实生成所有配置,我使用如下所示的findall:

findall(P-M-R-C-A-V-S-D-H,
(processor(P,Proc_price,Price_range),motherboard(M,Motherboard_price, 
Price_range), ram(R,Ram_price,Price_range),case(C,Case_price, 
Price_range),ali(A,Ali_price, Price_range),video_card(V,Vga_price, 
Price_range),ssd(S,Ssd_price, Price_range), monitor(D,Monitor_price, 
Price_range),hdd(H,Hdd_price, Price_range)),Res).

但我收到了这些错误:

Warning:  Singleton variables: [Proc_price,Motherboard_price,Ram_price,Case_price,Ali_price,Vga_price,Ssd_price,Monitor_price,Hdd_price,Res]
ERROR:  No permission to modify static procedure `findall/3'
        Defined at c:/program files/swipl/boot/bags.pl:88

我应该生成low_range的所有配置,中间范围的所有配置以及所有配置检查,如果总组件价格的价值存储在' price'变量

1 个答案:

答案 0 :(得分:1)

定义查询 Prolog程序(主要)是在不同环境中进行的单独活动。

您的问题始于您在Prolog源文件中编写的 definitions 。没关系。

但是您可能希望运行 findall/3查询并观察其结果。您不在源文件中编写查询;您将它们输入到Prolog的交互式提示中。有点模糊的“无权修改静态过程findall/3”错误消息说Prolog在预期谓词定义的地方遇到了涉及findall/3的内容,即在源文件中。但您并不是说使用findall/3作为findall/3的定义。

如果我将组件定义添加到源文件中(并修复第一行中缺少的句点),然后运行findall/3查询,那么您的程序对我有用“ Prolog的互动提示:

$ swipl -q -s foo.pl 
?- findall(P-M-R-C-A-V-S-D-H,
|    (processor(P,Proc_price,Price_range),motherboard(M,Motherboard_price, 
|    Price_range), ram(R,Ram_price,Price_range),case(C,Case_price, 
|    Price_range),ali(A,Ali_price, Price_range),video_card(V,Vga_price, 
|    Price_range),ssd(S,Ssd_price, Price_range), monitor(D,Monitor_price, 
|    Price_range),hdd(H,Hdd_price, Price_range)),Res).
Res = [].

一些提示:写出如此巨大的目标,特别是如此巨大的findall/3目标,是一种痛苦。始终(仅限专家:几乎总是)将您想要传递给findall/3的目标放入一个单独的,命名良好的谓词中,例如:

configuration(P, M, R, C, A, V, S, D, H) :-
    processor(P, _Proc_price, Price_range),
    motherboard(M, _Motherboard_price, Price_range),
    ram(R, _Ram_price, Price_range),
    case(C, _Case_price, Price_range),
    ali(A, _Ali_price, Price_range),
    video_card(V, _Vga_price, Price_range),
    ssd(S, _Ssd_price, Price_range),
    monitor(D, _Monitor_price, Price_range),
    hdd(H, _Hdd_price, Price_range).

然后您可以将其运行为:

?- findall(P-M-R-C-A-V-S-D-H, configuration(P, M, R, C, A, V, S, D, H), Res).
Res = [].

那不是更好吗?这也可以更容易地测试这个谓词并理解为什么它没有结果。

您还需要了解单个变量警告是什么以及为什么在执行任何其他操作之前应该修复它们。 (我在上面的谓词中已经为你处理了这个问题。)