Ответ в теме: Самое высокое дерево на Prolog:

      Комментарии к записи Ответ в теме: Самое высокое дерево на Prolog: отключены
#2575

Сначала Вам нужно объявить типы данных (возможные варианты деревьев).

domains
    tree_d = sosna; bereza; lipa; topol; el; klen

Затем, описать виды деревьев в базе данных:

predicates
    nondeterm tree(tree_d)
clauses	
    tree(sosna). 
    tree(bereza).
    tree(lipa).
    tree(topol).
    tree(el).
    tree(klen).

Уже сейчас вы можете получить два дерева из базы данных, но чтобы сравнивать их высоту — нужно описать соответствующие факты из задачи:

    tall_fact(lipa, klen).
    tall_fact(sosna, topol).
    
    lower_fact(bereza, topol).
    lower_fact(lipa, bereza).
    lower_fact(sosna, el).
    lower_fact(X, Y):-
    	tall_fact(Y, X).

Мы описали тут такие факты, как «липа выше клена», «береза ниже тополя». Кроме того, предикат lower_fact при отсутствии информации о высоте деревьев вызывает предикат tall_fact. Теперь мы можем сравнивать высоту деревьев, порядок которых фиксирован в задаче, однако не можем сравнить например березу и ель, для этого нам нужен еще один предикат:

lower(X, Y):- % X < Y
    	lower_fact(X, Y), !;
    	lower_fact(Z, Y), lower(X, Z), !. % such Z < Y as X < Z

Предикат lower принимает два дерева и пытается получить информацию об их сравнительной высоте из lower_fact. Если это не получается, то выполняет поиск нового дерева, которое ниже второго, но выше первого — если поиск удачен, то первое дерево ниже второго.

Наконец нам потребуется предикат, выполняющий обратную проверку:

tall(X, Y):-
     lower(Y, X).

В секции predicates все эти предикаты могли бы быть описаны следующим образом:

predicates
    nondeterm tall_fact(tree_d, tree_d)
    nondeterm lower_fact(tree_d, tree_d)
    
    lower(tree_d, tree_d)
    tall(tree_d, tree_d)

Мы можем утверждать, что дерево является самым высоким, если нет никаких других деревьев выше, и самым низким — если нет деревьев ниже:

goal
    tree(SamoeNizkoe),
    NOT(lower(_, SamoeNizkoe)),
    
    tree(SamoeVisokoe),
    NOT(tall(_, SamoeVisokoe)). 

Вложения: