Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Простой пример с городами 
V
    Опции темы
Ak47black
  Дата 19.9.2010, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



Здравствуйте.
Я новичок в prolog и с интересом пытаюсь его освоить.
Но вот некак немогу понять как выполнить простейшие задание
Есть карта городов
user posted image
На ней изображены названия городов a1, направления соединяющих дорог и их длины.

Нужно сделать предикат, который определяет можно-ли проехать из города X в город Y, что-бы общие проеханное растояние не превышало L км.

Вот так я пробую решить
Код

doroga(a2, a1, 10).
doroga(a3, a2, 20).
doroga(a3, a4, 20).
doroga(a5, a3, 30).

nepr(X, Y, L):- doroga(X, Y, L1), L>=L1, !; L>0, doroga(X, Y1, L1), L1=L-L1, doroga(Y1, Y, L1).


Но при наборе
Код

nepr(a5, a2, 50).

получаю false.

Подскажите пожалуйста, я сделал семантическую ошибку?  smile 

Это сообщение отредактировал(а) Ak47black - 19.9.2010, 11:01
PM MAIL   Вверх
Фантом
Дата 19.9.2010, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 6
Всего: 49



Да. Конструкция "L1=L-L1" в Прологе даст совершенно не тот результат, который планировался (по-видимому, предполагалось обычное присваивание?).

В стандартном Прологе (насколько можно говорить о существовании стандарта) и в большинстве диалектов "=" - это оператор сравнения, не вычисляющий свои операнды. Т.е. при сложных выражениях в качестве операндов получить в качестве  результата true можно только в том случае, если выражения тождественно совпадают. При этом даже X+Y=Y+X выдаст false.

Оператором, вычисляющим значение, является "is" (и его можно заменять на "=" в некоторых диалектах языка), так что, казалось бы, надо было написать "L1 is L-L1", однако и это тоже не пройдет - переменная L1 уже конкретизирована, и переписать ее значение в пределах этой ветки предиката нельзя. Так что на самом деле надо заводить какую-то новую переменную, а на будущее учесть, что оператора присваивания в Прологе, вообще говоря, просто нет.

В итоге код превращается в нечто такое:
Код

doroga(a2, a1, 10).
doroga(a3, a2, 20).
doroga(a3, a4, 20).
doroga(a5, a3, 30).

nepr(X, Y, L):- doroga(X, Y, L1), L>=L1, !.
nepr(X, Y, L):- L>0, doroga(X, Y1, L1), L2 is L-L1, doroga(Y1, Y, L2).

Он на "nepr(a5, a2, 50)" будет реагировать правильно.

Однако на самом деле тут есть еще как минимум две ошибки, Вы просто не успели с ними столкнуться.

Во-первых, наличие правила "doroga(a2, a1, 10)" не означает справедливости "doroga(a1, a2, 10)". Вы-то знаете, что дороги в обе стороны одинаковы по длине, но программе об этом сообщить забыли. Поэтому запрос "nepr(a2, a5, 50)", вопреки желаемому, выдаст false.

Во-вторых, предикат nepr нужно сделать рекурсивным. В нынешнем его виде он сможет найти только такие пути, которые состоят из одной или двух дорог, не больше. Так что вместо второго вызова doroga во второй альтеративе nepr должен быть "nepr(Y1, Y, L2)".

PM   Вверх
Ak47black
Дата 19.9.2010, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2205
Регистрация: 2.12.2005

Репутация: нет
Всего: 0



О, спасибо что так Вы подробно расписали.

Цитата(Фантом @  19.9.2010,  11:37 Найти цитируемый пост)
Оператором, вычисляющим значение, является "is" (и его можно заменять на "=" в некоторых диалектах языка), так что, казалось бы, надо было написать "L1 is L-L1", однако и это тоже не пройдет - переменная L1 уже конкретизирована, и переписать ее значение в пределах этой ветки предиката нельзя. Так что на самом деле надо заводить какую-то новую переменную, а на будущее учесть, что оператора присваивания в Прологе, вообще говоря, просто нет.

Да. Вот тут у меня и была проблема из-за незнания.


Цитата(Фантом @  19.9.2010,  11:37 Найти цитируемый пост)
Во-первых, наличие правила "doroga(a2, a1, 10)" не означает справедливости "doroga(a1, a2, 10)". Вы-то знаете, что дороги в обе стороны одинаковы по длине, но программе об этом сообщить забыли. Поэтому запрос "nepr(a2, a5, 50)", вопреки желаемому, выдаст false.

Тут моя вина, я тут забыл чётко указать что дороги у меня с односторонним движением.(или каким словом можно правильно выразится, когда говорят о дороге с односторонним движением  smile  ?)

Это сообщение отредактировал(а) Ak47black - 19.9.2010, 11:56
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума Prolog
Void
  • Пожалуйста, создавайте темы с содержательными названиями.
  • Уважаемые учащиеся, здесь всегда рады помочь Вам, но не делать за Вас вашу работу. У вас гораздо больше шансов получить помощь, если Вы приложите усилия и поделитесь с нами проблемами и результатами. В противном случае добро пожаловать в раздел Центр Помощи.
  • Получив ответ на интересующий Вас вопрос, не забудьте пометить его как решённый.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Void.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Prolog | Следующая тема »


 




[ Время генерации скрипта: 0.0430 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.