Как правильно отфильтровать предложение, которое возвращает несколько дублированных значений? - PullRequest
2 голосов
/ 13 июня 2019

Я пытаюсь правильно отфильтровать значения, возвращаемые предложением (он возвращает несколько дублированных значений).Мне трудно понять логическое программирование, извините, если это глупый вопрос.

Это мои факты / предикаты:

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

Я думаю, что где-то в супердорогих делает что-то, как все * все?

Ответы [ 2 ]

3 голосов
/ 13 июня 2019

Самый дорогой дом в городе таков, что ни один другой дом в этом городе не стоит дороже его:

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.
0 голосов
/ 18 июня 2019

Вы можете найти простое решение, если подумаете о проблеме следующим образом.

Человек Х удовлетворяет вашим условиям тогда и только тогда, когда у Х есть дом в каком-то городе Y, и никого нетеще в Y дом стоит как минимум половину цены 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, _ ).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...