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

标签 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).

我认为 superExperiment 中的某个地方正在做类似每个人*每个人的事情?

最佳答案

城镇中最昂贵的房屋是该城镇中没有其他房屋比它更贵的:

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.

关于prolog - 如何正确过滤返回多个重复值的子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56573203/

相关文章:

list - 在 Prolog 中交换列表前缀和后缀

prolog - 带有序言的填字游戏

prolog - Prolog 中的 DNA 匹配

prolog - 在 SWI-Prolog 中聚合谓词

list - Prolog 代码给出了两个不同的结果

专家系统中的Prolog和 "reverse"输出

model - 可以在序言中模拟一个简单的 CPU 吗?

计算阶乘的 Prolog 代码

prolog - 在列表中查找第二个最小值

Prolog - 生成适合给定范围的数字