如何正确过滤返回多个重复值的子句?

时间:2019-06-13 04:00:48

标签: prolog

我试图正确过滤从子句返回的值(它返回多个重复的值)。我很难理解逻辑编程,很抱歉,这是一个愚蠢的问题。

这些是我的事实/谓词:

home(peter, sanFrancisco, 1000).
home(ash, sanFrancisco, 100).
home(juan, sanFrancisco, 400).
home(juan, california, 700).
home(ash, california, 600).
home(peter, california, 500).
home(peter, vegas, 100).
home(ash, vegas, 80).
home(juan, vegas, 60).

我想做的就是检索名称;条件是,我必须只检索那些来自某个城市的房屋是那里最昂贵的房屋,而且如果来自同一城市的第二贵的房屋的价格低于第一座城市的价格的一半,则必须取回。我不能使用列表。

每个城市中最昂贵的商品:

home(peter, sanFrancisco, 1000).
home(juan, california, 700).
home(peter, vegas, 100).

每个城市的第二贵:

home(juan, sanFrancisco, 400).
home(ash, california, 600).
home(ash, vegas, 80).

我期望得到的结果:

peter.

到目前为止我已经尝试过但没有成功。.

%Return the most expensive from each city.
theMostExpensive(Name, City):-
    home(Name, City, Price),
    fromEach(City, Price).

fromEach(City, Price):-
    forall(home(_, City, Price2), Price>= Price2).

%Return the second most expensive from each city. Not sure if working correctly.
secondMostExpensive(Name, City):-
    owner(home),
    not(theMostExpensive(Name, City)),
    theMostExpensive(Name2, City),
    Name \= Name2.

%Return a lot of duplicated values and wrong..
superExpensive(Name):-
    theMostExpensive(Name, City),
    secondMostExpensive(Name2, City),
    Name \= Name2,
    City \= City2,
    home(Name, City, Price),
    home(Name2, City2, Price2),
    Price > Price2 + (Price / 2).

我认为superExpensive中的某处正在像每个人*每个人一样做事?

2 个答案:

答案 0 :(得分:3)

一个镇上最昂贵的房屋是那个镇上没有其他房屋比它更贵的了:

most_expensive( home( Name, Town, Price)):-
  home( Name, Town, Price),
  \+ (home( _, Town, P), P > Price).

这使我们

5 ?- most_expensive( H ).
H = home(peter, sanFrancisco, 1000) ;
H = home(juan, california, 700) ;
H = home(peter, vegas, 100) ;
false.

城镇中第二昂贵的房屋是房屋中最昂贵的房屋,而不是该镇中最昂贵的房屋:

second_most_expensive( home( Name, Town, Price)):-
  most_expensive( home( _, Town, TopPrice) ),
  home( Name, Town, Price), Price < TopPrice,
  \+ (home( _, Town, P), P < TopPrice, P > Price).

这使我们

8 ?- second_most_expensive( H ).
H = home(juan, sanFrancisco, 400) ;
H = home(ash, california, 600) ;
H = home(ash, vegas, 80) ;
false.

然后,用

top_house_owner( Name ) :-
  most_expensive( home( Name, T, P) ),
  second_most_expensive( home( _, T, P2 ) ),
  P2 < P div 2.

我们得到

12 ?- top_house_owner( N ).
N = peter ;
false.

答案 1 :(得分:0)

如果通过以下方式考虑问题,则可以找到简单的解决方案。

X且仅当X在某个城市Y拥有房屋且Y中没有其他人的房屋价格至少为X的一半时,X人才满足您的条件。

% true if Name2's home is at least half of the price of Name1's
aboveHalf( City, Name1, Name2 ) :-
  home( Name1, City, P1 ),
  home( Name2, City, P2 ),
  Name1 \= Name2,
  P2 > P1 div 2.

superExpensive( Name ) :-
  home( Name, City, _ ),
  \+ aboveHalf( City, Name, _ ).