List prolog-按条件从事实创建列表

List prolog-按条件从事实创建列表,list,prolog,fact,List,Prolog,Fact,我试图从SWI Prolog中的事实创建列表。 有大量的exapmles,但我不知道如何根据标准创建列表。 你可以在下面看到我的代码。 Predicateextract没有像我预期的那样工作 我需要: L = [depos(sbr, 3000, 3), depos(psb, 4000, 4), depos(hkb, 5000, 5)] 但我得到: ?- deposit(X), extract(X, 3, 5, Ls). X = depos(sbr, 3000, 3), Ls = [depos

我试图从SWI Prolog中的事实创建列表。 有大量的exapmles,但我不知道如何根据标准创建列表。 你可以在下面看到我的代码。 Predicateextract没有像我预期的那样工作

我需要:

L = [depos(sbr, 3000, 3), depos(psb, 4000, 4), depos(hkb, 5000, 5)]
但我得到:

?- deposit(X), extract(X, 3, 5, Ls).

X = depos(sbr, 3000, 3),
Ls = [depos(sbr, 3000, 3)] ;
X = depos(psb, 4000, 4),
Ls = [depos(psb, 4000, 4)] ;
X = depos(hkb, 5000, 5),
Ls = [depos(hkb, 5000, 5)] ;
false.
我错了什么

% vim: ft=prolog

depos(rsb, 1000, 1).
depos(vtb, 2000, 2).
depos(sbr, 3000, 3).
depos(psb, 4000, 4).
depos(hkb, 5000, 5).
depos(mkb, 6000, 6).

deposit(depos(Bank, Body, Rate)) :- depos(Bank, Body, Rate).

bank(depos(Bank,_,_), Bank).
body(depos(_,Body,_), Body).
rate(depos(_,_,Rate), Rate).

% Usage:
% deposit(X), bank(X, Ba), body(X, Bo), rate(X, Ra).

% Usage: create List from Body
% ?- findall(Bo, depos(Ba, Bo, Ra), L).
% L = [1000, 2000, 3000, 4000, 5000, 6000].

% Usage: create List from Rate
% ?- findall(Ra, depos(Ba, Bo, Ra), L).
% L = [1, 2, 3, 4, 5, 6].

profit(X, Prof) :-
  body(X, Body),
  rate(X, Rate),
  Prof is Body * Rate.

% Usage:
% ?- deposit(X), profit(X, Pro).
% X = depos(rsb, 1000, 1),
% Pro = 1000 ;
% X = depos(vtb, 2000, 2),
% Pro = 4000 ;

critRate(X, From, Before) :-
  rate(X, Rate),
  Rate >= From,
  Rate =< Before.

% Usage:
% ?- deposit(X), critRate(X, 3, 5).
% X = depos(sbr, 3000, 3) ;
% X = depos(psb, 4000, 4) ;
% X = depos(hkb, 5000, 5) ;

critProf(X, From, Before, Prof) :-
  profit(X, Prof),
  Prof >= From,
  Prof =< Before.

% Usage:
% ?- deposit(X), critProf(X, 9000, 25000).
% X = depos(sbr, 3000, 3) ;
% X = depos(psb, 4000, 4) ;
% X = depos(hkb, 5000, 5) ;

% How to create List Ls from deposit with Rate From to Before ???
extract(X, From, Before, Ls) :-
  bagof(X, critRate(X, From, Before), Ls).

% Expected:
% L = [depos(sbr, 3000, 3), depos(psb, 4000, 4), depos(hkb, 5000, 5)]
%vim:ft=prolog
仓库(rsb,1000,1)。
仓库(悉尼威立雅运输局,2000年,第2期)。
仓库(sbr,3000,3)。
仓库(psb,4000,4)。
仓库(hkb,5000,5)。
仓库(mkb,6000,6)。
存款(存款(银行、机构、利率):存款(银行、机构、利率)。
银行。
正文(depos,body,body,body)。
比率(depos(u,u,rate),rate)。
%用法:
%存款(X)、银行(X、Ba)、机构(X、Bo)、利率(X、Ra)。
%用法:从正文创建列表
%?findall(Bo,depos(Ba,Bo,Ra),L)。
%L=[10002000300040006000]。
%用法:从速率创建列表
%?findall(Ra,depos(Ba,Bo,Ra),L)。
%L=[1,2,3,4,5,6]。
利润(X,教授):-
主体(X,主体),
速率(X,速率),
Prof是Body*Rate。
%用法:
%-存款(X)、利润(X、专业)。
%X=仓库(rsb,1000,1),
%Pro=1000;
%X=仓库(vtb,2000,2),
%Pro=4000;
临界值(X,起始,起始):-
速率(X,速率),
速率>=从,
速率=<之前。
%用法:
%-沉积物(X),临界值(X,3,5)。
%X=仓库(sbr,3000,3);
%X=仓库(psb,4000,4);
%X=仓库(hkb,5000,5);
critProf(X,From,Before,Prof):-
利润(X,教授),
教授>=来自,
Prof=<之前。
%用法:
%-存款(X),critProf(X,9000,25000)。
%X=仓库(sbr,3000,3);
%X=仓库(psb,4000,4);
%X=仓库(hkb,5000,5);
%如何使用从到之前的利率从存款创建列表Ls???
摘录(X,From,Before,Ls):-
bagof(X,critRate(X,From,Before),Ls)。
%预期:
%L=[仓库(sbr,3000,3),仓库(psb,4000,4),仓库(hkb,5000,5)]
我认为您的问题与使用“访问器”构造代码有关,如以下3

bank(仓库,银行,银行)。
正文(depos,body,body,body)。
比率(depos(u,u,rate),rate)。
并以实用的方式使用它们

按OP编辑

你能更详细地解释一下这方面吗?我是Prolog的新手。 我在Bratko读到了有关存取器的内容,并在没有完全理解的情况下使用了它。 我什么时候能用,什么时候不能用

Prolog有一个关系数据模型,所以您应该重新考虑您的工作流。例如,用这种方式将extract/4简化为extract/3

提取(从、之前、Ls):-
bagof(X,(沉积物(X),临界值(X,从,之前)),Ls)。
您将得到您需要的:

?-提取(3,5,Ls)。
Ls=[仓库(sbr,3000,3),仓库(psb,4000,4),仓库(hkb,5000,5)]。
那就行了!谢谢。

按OP编辑

我为critProf

extract_prof4(From, Before, Prof, Ls) :-
  bagof(X, (deposit(X), critProf(X, From, Before, Prof)), Ls).
而且它再也不起作用了

?- extract_prof4(3000,25000,P,L).
P = 4000,
L = [depos(vtb, 2000, 2)] ;
P = 9000,
L = [depos(sbr, 3000, 3)] ;
但是如果我添加了另一个谓词(没有Prof作为参数),如下所示:

critProf3(X, From, Before) :-
  profit(X, Prof),
  Prof >= From,
  Prof =< Before.

extract_prof(From, Before, Ls) :-
  bagof(X, (deposit(X), critProf3(X, From, Before)), Ls).

为什么?

由于您的
From
Before
是自由变量,它们将“绑定”。这不是讨论站点。你编辑卡佩拉的答案来提出新问题是非常错误的。因为你是一个新用户,我现在不会否决这个问题,但是如果你不遵循这里的指导原则,我会重新考虑。我也不是这里所有规则的粉丝,但是如果我们都做了我们想要的,那么在我们需要的时候就很难找到答案。为什么
bagof/3
而不是
setof/3
?- extract_prof(3000,25000,L).
L = [depos(vtb, 2000, 2), depos(sbr, 3000, 3), depos(psb, 4000, 4), depos(hkb, 5000, 5)].