Prolog 序言:类型错误:应为“可评估”,找到“[]”(空列表)

Prolog 序言:类型错误:应为“可评估”,找到“[]”(空列表),prolog,Prolog,我试图从满足给定约束的列表中删除元素。用户输入预算,价格高于预算的项目将被删除。我在查阅文件时遇到类型错误 :- use_module(library(lists)). main(_) :- write('Enter budget'), nl, read(Budget), write(Buget), numlist(1,168,MasterList), BudgetList is [], apply_budget(MasterList, Budget

我试图从满足给定约束的列表中删除元素。用户输入预算,价格高于预算的项目将被删除。我在查阅文件时遇到类型错误

:- use_module(library(lists)).

main(_) :- 
   write('Enter budget'),
   nl,
   read(Budget),
   write(Buget),
   numlist(1,168,MasterList),
   BudgetList is [],
   apply_budget(MasterList, Budget, BudgetList),
   write(BudgetList).

apply_budget([],_,_).
apply_budget([H | T], B, R) :-
   price(H, Pr),
   (Pr > B ->
       apply_budget(T, B, R);
       append(R, [H], L),
       R is L,
       apply_budget(T, B, R)
   ).

你写这篇文章的时候,就好像这是一种命令式语言。您无法在Prolog中从列表中删除元素。在Prolog中,一切都是不可变的。如果您有一个列表,那么该列表将无法更改。你只能创造新事物。因此,如果您想从列表中删除元素,您将创建一个新列表,其中不包含要删除的元素

下面是您应该如何编写apply_预算谓词:

apply_budget([],_,[]).
apply_budget([H|Ts],B,Rs) :- price(H, P), P > B, !, apply_budget(Ts,B,Rs).
apply_budget([H|Ts],B,[H|Rs]) :- apply_budget(Ts,B,Rs).
第一种情况是,当你有一个空的清单,那么你不关心预算,一个空的清单应该出来

第二种情况是,当值H大于B时,我们丢弃H并递归。这个cut用于防止回溯,以便在出现故障时不会尝试第三个谓词

第三种情况是当H小于或等于B时。在这种情况下,我们通过构建而不是将H作为[H | Rs]删除到输出来保持H

可以通过以下方式编写代码来删除切口:

apply_budget([],_,[]).
apply_budget([H|Ts],B,Rs) :- price(H, P), P > B, apply_budget(Ts,B,Rs).
apply_budget([H|Ts],B,[H|Rs]) :- price(H, P), P =< B, apply_budget(Ts,B,Rs).

我认为这会变得不易管理,但你可以决定你更喜欢哪一个。

你的程序是以命令式的方式编写的,比如你写appender,[H],L,然后R就是L。这总是会失败的,因为你只能在Prolog中分配一个变量,列表不能等于添加了元素的列表。Willem就是其中之一。你写这篇文章的时候,就好像这是一种命令式语言。您无法在Prolog中从列表中删除元素。在Prolog中,一切都是不可变的。如果您有一个列表,那么该列表将无法更改。你只能创造新事物。因此,如果你想从列表中删除元素,你会创建一个没有要删除元素的新列表。为什么不在price/2之后使用if-else呢?@false-因为谓词的开头有差异-Rs与[H | Rs]。@false-我最后使用apply_budget[H | Ts],B,Zs:-H>B->Zs=Rs else Zs=[H | Rs],apply|budgets,B,在草莓序言里。我觉得它看起来不干净。但它确实有效。s/else/;/至少效率要高得多,而且我认为这是非常有效的clean@false-你如何衡量效率?