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

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

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 1 год, 3 мес. назад.

  • Автор
    Сообщения
  • #2574

    questioner
    Участник

    Здравствуйте, мне задали решить логическую задачу:

    Возле почты растут 6 деревьев: сосна, береза, липа, тополь, ель и клен. Какое из этих деревьев самое высокое и какое самое низкое, если известно, что береза ниже тополя, а липа выше клена, сосна ниже ели, липа ниже березы, сосна выше тополя?

    В решении мне нельзя использовать списки, поэтому я не могу решить ее так, как у вас решены остальные задачи на установления соответствия. Помогите решить задачу.

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

    Вложения:

Для ответа в этой теме необходимо авторизоваться.