Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Prolog
Перезагрузить страницу Закрываем тему по формуле... Помогите найти ошибку....
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
yurij_i yurij_i вне форума
Member
 
Сообщений: 24
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 07.11.2004
По умолчанию Закрываем тему по формуле... Помогите найти ошибку.... - 08.11.2004, 18:47

Написал, не работает, зараза....
Может кто поможет???????

Условие:
есть победители формулы 1,
получается, что гонщик 1 занял место или 1 или 2 или 3,
гонщик 2 ни первый ни последний,
гонщик 3, 3 место или 4 или 5
гонщик 4 место выше чем гонщик 3
гонщик 5 выше, чем гонщик 2....

Код:
domains
   driver = string
   pl = integer

predicates
   nondeterm rating(driver,pl)  
   nondeterm showrating()
   
clauses
   rating(petya,X):-
     X=1; X=2; X=3.
   rating(sasha,X):-
     X=2; X=3; X=4.
   rating(valentin,X):-
     X=3; X=4; X=5.
   rating(yura,X):-
     rating(valentin,X1),
     X<X1.
   rating(stepa,X):-
     rating(sasha,X1),
     X<X1.
   
   showrating():-
     rating(petya,X),
     write("petya ",X),nl,
     rating(sasha,X1),
     write("sasha ",X1),nl,
     rating(valentin,X2),
     write("valentin ",X2),nl,
     rating(yura,X3),
     write("yura ",X3),nl,
     rating(stepa,X4),
     write("stepa ",X4),nl,
     X<>X1,X2<>X1,X<>X2, X3<>X2, X4<>X3.
[/url]
Ответить с цитированием
  (#2 (permalink)) Старый
Anonymous
Guest
 
Сообщений: n/a
По умолчанию 08.11.2004, 23:01

Проще всего, хоть и неуклюже, сделать так
Код:
domains 
   driver = string 
   pl = integer 
predicates 
   nondeterm rating(driver,pl)  
   nondeterm showrating() 
clauses 
   rating(petya,X):- X=1; X=2; X=3. 
   rating(sasha,X):- X=2; X=3; X=4. 
   rating(valentin,X):- X=3; X=4; X=5. 
   rating(yura,X):- X=1; X=2; X=3; X=4.
   rating(stepa,X):- X=1; X=2; X=3. 
   showrating():- 
     rating(petya,X), 
     rating(sasha,X1), X<>X1,
     rating(valentin,X2), X<>X2,X1<>X2,
     rating(yura,X3),X3<X2, X<>X3,X1<>X3,
     rating(stepa,X4),X4<X1, X<>X4,X2<>X4,X3<>X4,
     write("petya ",X),nl, 
     write("sasha ",X1),nl, 
     write("valentin ",X2),nl, 
     write("yura ",X3),nl,
     write("stepa ",X4),nl,nl,      
     fail; true. 
  goal  
  showrating().
Предикат fail заставляет выдать все возможные решения, с помощью отката.
Ответить с цитированием
  (#3 (permalink)) Старый
Mnior Mnior вне форума
Member
 
Сообщений: 487
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 19.12.2002
По умолчанию Re: Закрываем тему по формуле... Помогите найти ошибку.... - 09.11.2004, 02:26

Цитата:
Originally posted by yurij_i
[b]Написал, не работает, зараза....
Мужик, ты настоящий пацан - у тебя прога работает! Вот исправленные глюги, о которых я тебе писал ранее:
Код:
Domains
   driver = string
   pl = integer
Predicates
   nondeterm rating(driver,pl)
   nondeterm all_place(pl)
   nondeterm showrating
Goal showrating.
Clauses
    rating(petya, X):- X = 1; X = 2; X = 3.
    rating(sasha, X):- X = 2; X = 3; X = 4.
    rating(valentin, X):- X = 3; X = 4; X = 5.
    rating(yura, X):-
  rating(valentin, X1),
  all_place(X), % !!!
  X < X1.
    rating(stepa,X):-
  rating(sasha,X1),
  all_place(X), % !!!
  X < X1.

    all_place(X):- X = 1; X = 2; X = 3; X = 4; X = 5.

    showrating():-
  rating(petya, X),
  rating(sasha, X1),
  rating(valentin,X2),
  rating(yura,X3),
  rating(stepa,X4), 
  X1 <> X,
  X2 <> X, X2 <> X1,
  X3 <> X2,
      X3 <> X, X3 <> X1, % !!!
  X4 <> X3,
      X4 <> X, X4 <> X1, X4 <> X2, % !!!

  write("petya ", X),nl,
  write("sasha ", X1),nl,
  write("valentin ",X2),nl,
  write("yura ",X3),nl,
  write("stepa ",X4),nl,
  
  nl,nl,fail. % !!!
Плюс, я добавил ещё условия, которые ты прорустил, они помечены коментарием (всё что за знаком "%"). Из-за особенностей этой реализации ПроЛога, wite пиши в конце, они как бы подитоживают найденый результат, а то если будешь писать их в середине и с fail, то результаты помешаются в кучу.

Значит план таков: надо изучить типы данных и вместе с пими списки, а также принцип работы этого ПроЛога.
Ответить с цитированием
  (#4 (permalink)) Старый
Anonymous
Guest
 
Сообщений: n/a
По умолчанию Re: Закрываем тему по формуле... Помогите найти ошибку.... - 09.11.2004, 15:39

Не подскажите как вывести еще количесвто решений???

понятно, что нужно использовать перемнную, которая будет инкримироваться каждый раз, но в этом решении не совсем понятно, как и куда ее запихнуть???

спасибо всем большой за подсказки!!!
Ответить с цитированием
  (#5 (permalink)) Старый
Mnior Mnior вне форума
Member
 
Сообщений: 487
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 19.12.2002
По умолчанию Re: Закрываем тему по формуле... Помогите найти ошибку.... - 09.11.2004, 19:11


Вот я сморозил.
Цитата:
Originally posted by Mnior+-->
Цитата:
<!--QuoteBegin-Anonymous
Цитата:
[b]Не подскажите как вывести еще количесвто решений??? ...

Ба, во закрутил, хрен врубишься ...


Блин, а зачем это во внутренней цели, это ж работа среды. А прога этим не должна заниматься. Надо ставить правильные цели.
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Anonymous
Guest
 
Сообщений: n/a
По умолчанию 10.11.2004, 01:27

Чтобы не было лишних решений, мне кажется, что лучше писать кто какое место выше занял прямо в предикате showrating() - X3<X2 и X4<X1.
В следующей программе подсчитывается число решений, но я не знаю, можно ли так делать в Турбо Прологе. Изменения по сравнению с моей предыдущей программой отмечены знаком %. Результаты те же самые.
Код:
domains 
   driver = string 
   pl = integer 
facts      %
single counter(integer)  %
predicates 
   nondeterm rating(driver,pl)  
   nondeterm showrating() 
clauses 
   rating(petya,X):- X=1; X=2; X=3. 
   rating(sasha,X):- X=2; X=3; X=4. 
   rating(valentin,X):- X=3; X=4; X=5. 
   rating(yura,X):- X=1; X=2; X=3; X=4; X=5.  %
   rating(stepa,X):- X=1; X=2; X=3; X=4; X=5. %
   showrating():- 
     rating(petya,X), 
     rating(sasha,X1), X<>X1, 
     rating(valentin,X2), X<>X2,X1<>X2, 
     rating(yura,X3),X3<X2, X<>X3,X1<>X3, 
     rating(stepa,X4),X4<X1, X<>X4,X2<>X4,X3<>X4, 
     write("petya ",X),nl, 
     write("sasha ",X1),nl, 
     write("valentin ",X2),nl, 
     write("yura ",X3),nl, 
     write("stepa ",X4),
     counter(N),N1=N+1,assert(counter(N1)), %
     nl,nl,fail; true. 
     counter(0).      %
  goal  
  showrating(),counter(N).    %
Ответить с цитированием
  (#7 (permalink)) Старый
Mnior Mnior вне форума
Member
 
Сообщений: 487
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 19.12.2002
По умолчанию Re: Закрываем тему по формуле... Помогите найти ошибку.... - 11.11.2004, 12:54

Цитата:
Originally posted by Anonymous
[b]понятно, что нужно использовать перемнную, которая будет инкримироваться ...
Это по императивиски.
Можно по другому.


Чтоб особо не врубаться, как фуниклирует ПроЛог, можно воспользоваться встроенным предикатом-предложением "findall"-ом. Он ищет все решения указанного предиката-предложения и в добавок гененрит список результатов. И ентим списком мы и воспользуемся. Вот прога:
Код:
Domains
   driver = string
   pl = integer
   element = l(pl, pl, pl, pl, pl)
%   analog_list = list(element, analog_list);end_list
   list = element*
Predicates
   nondeterm rating(driver,pl)
   nondeterm all_place(pl)
   nondeterm showrating(element)
   determ len(list, integer)
Goal
    findall(L, showrating(L), List),
    len(List, Num),
    write("Количество решений: ", Num).
Clauses
   rating(petya, X):- X = 1; X = 2; X = 3.
   rating(sasha, X):- X = 2; X = 3; X = 4.
   rating(valentin, X):- X = 3; X = 4; X = 5.
   rating(yura, X):-
      rating(valentin, X1),
      all_place(X),
      X < X1.
   rating(stepa,X):-
      rating(sasha,X1),
      all_place(X),
      X < X1.

   all_place(X):- X = 1; X = 2; X = 3; X = 4; X = 5.

   showrating(l(X, X1, X2, X3, X4)):-
      rating(petya, X),
      rating(sasha, X1),
      rating(valentin,X2),
      rating(yura,X3),
      rating(stepa,X4),
      X1 <> X,
      X2 <> X, X2 <> X1,
      X3 <> X2, X3 <> X, X3 <> X1,
      X4 <> X3, X4 <> X, X4 <> X1, X4 <> X2,
      write("Petya ", X, ", Sasha ", X1, ", Valentin ", X2, ", Yura ", X3, ", Stepa ", X4), nl.

   len([_Head|Tail], Num):-
      len(Tail, NumTail),
      Num = NumTail + 1.
   len([], 0).
Вот мы и столкнулись в лобешник с типами данных, списками и рекурсией. Многовато сразу, но мы ведь мужики.
Видно что мы вырезали непонятный fail. Вывели все неременные в структуру l(X, X1, X2, X3, X4), c назнанием типа данных element.
Типы данных в ПроЛоге очень простые и описываются, как и предлдожения, с использованием "," и ";".
Тип данных это варианты структур:
Код:
ТипДанных = Структура1; Структура2; Структура
Смысл точки с запятой такой же - ИЛИ. А структура должна всегда иметь имя и если нуна, то и список составных элементов, перечисленные через запятую, как видно смысл тот же - И:
Код:
Структура - Имя1(ТипДанныйх1, ТипДанных2, ТипДанных3)
или просто Структура - ПростоИмя. Или полной пример описания типа данных:
Код:
ТипДанных = Имя1(ТипДанных1, ТипДнных2); Имя2
В нашем случае:
Код:
element = l(pl, pl, pl, pl, pl)
Имя типа данных - element имеет один вариант структуры с именем l (Л - латинская), и состоит из пяти элементов с типом данных pl. Кстати в памяти не хранятся непосредственно имена структур, так что именуйте как вздумаете, не заботясь о размере памяти.
Ну коль всё так прото и банально, перейдём к варианту типов данных - списки. Список это связанные данные в одну цепочку. В ПроЛоге можно описать так:
Код:
analog_list = list(element, analog_list); end_list
Видно, что это либо пустой список (end_list) либо структура содержащая один элемент и ПодСписок: list(element, analog_list), как видно ПодСпсок - это тот же самый тип данных, что и список. Как всё просто, вот пример, как записывается список из 2 элементов:
Код:
Список = list(1,list(2,end_list))
Муторно, да?! А из-за того, что списками часто пользуются, то в ПроЛог добавили, за счёт препроцессорной обработки, консрукции вида: list_elements = element*, т.е. поставив в конце типа "*" (звёздочку) мы получаем список этого типа. А запись списков очень простой, вот всё варианты для понимания:
Код:
СписокИзОдногоЭлемента = [Элемент]
СписокИзТрёхЭлементов = [Элемент1, Элемент2, Элемент3]
ПустойСписок = []
Список = [ПервыйЭлемент | СписокИзОставшихсяЭлементов]
СписокСодержащийМинимумДваЭлемента = [ПервыйЭлемент, ВторойЭлемент | СписокОставшихсяЭлементов]
Это всё!

Продолжим.
Предикат findall(Cur, showrating(Cur), ListCur), имеет такую структуру:[list]

Ну далее осталась рекурсия. Она реализованна в предикате-предложении "len" находящий длину списка. Описание очень простое:
Если список пустой, то его длина "ноль", иначе (или) его длина на единицу больше, чем длина его подсписка (списка оставшихся элементов).
Видно, что предложение сосотоит из двух подпредложений (отделяемых ; - т.е. ИЛИ). Запишем первое "список пустой - его длина ноль":
Код:
len(List, Len):-
    List = [],
    Len = 0.
Соответсвенно упростив, получим:
Код:
len([], 0).
Кстати, упрощать так можно всё кострукции-структуры (ведь список это тоже структура), а вот математические выражения, как и говорилось ранее - это предикаты и их не засунешь в голову предложения.
Далее запишем второе подпредложение: его длина на единицу больше, чем длина его подсписка, или на ПроЛоге:
Код:
len(List, Num):-
      List = [_Head|Tail],
      len(Tail, NumTail),
      Num = NumTail + 1.
Или упрощённо:
Код:
len([_Head|Tail], Num):-
      len(Tail, NumTail),
      Num = NumTail + 1.
Последовательность, к сожалению, имеет значение, т.к. тупые матемматические предикаты в этом ПроЛоге не могут работать с переменными не имеющие ещё значения.
С рекурсией, да и вообще со сложными и большими программами работать без понимания фунчиклирования ПроЛога тяжело. Но в принципе можно.

Как работает ПроЛог - это тема следующей Лекции.
Ответить с цитированием
  (#8 (permalink)) Старый
Винитарх Винитарх вне форума
Специалист
 
Аватар для Винитарх
 
Сообщений: 7,988
Сказал(а) спасибо: 2
Поблагодарили 303 раз(а) в 303 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
По умолчанию 11.11.2004, 13:29

Alison пишет:
Цитата:
В следующей программе подсчитывается число решений, но я не знаю, можно ли так делать в Турбо Прологе.
Именно так делать и нужно!
А когда важно знать не только количество решений, но и сами решения, то можно воспользоваться findall().
Ответить с цитированием
  (#9 (permalink)) Старый
Mnior Mnior вне форума
Member
 
Сообщений: 487
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 19.12.2002
По умолчанию 14.11.2004, 13:39

Цитата:
Originally posted by Винитарх+-->
Цитата:
<!--QuoteBegin-Alison
Цитата:
[b]В следующей программе подсчитывается число решений, но я не знаю, можно ли так делать в Турбо Прологе.
Именно так делать и нужно!
Находить количество решений без самих решений, это для споров о скорости прог. Для комерческих реализаций, даже такой способ это неэфективно: "Зачем вычислять решения, если они не используются. А для нахождения количества лучше воспользоваться математической формулой.". В остальных случаях решения "головоломок" скорость особо не важна.
Посему, СОВЕТУЮ ТАК НЕ ДЕЛАТЬ. Т.к. это не логический подход, а императивный.

<Те же грабли ...>

Думаю, что хотя б некоторым надо задумываться, что проектирование нужно вести не только вниз, только пользоваться тем языком, той средой, теми технологиями которая есть, но и вверх, меняя сам язык, саму среду, саму реализацию, сами технологии и не ждать пока это сделают другие. Короче, немного смотреть в будущее.

Скажите, какова ценность императивных прог? Их цена в будущем?
Меняются технологии, меняются императивные языки. А какие языки не меняются? Вы согласитесь, чем более декларативный и прост язык, тем меньше он меняется.

Какие прологовские проги будут работать на разных реализациях? Имено, те, которые не имеют императивных элементов. Будет ли прога с assert-ом и retract-ом работать на паралельном прологе или с поиском в ширину? Скорее НЕТ чем да.
Ответить с цитированием
  (#10 (permalink)) Старый
Anonymous
Guest
 
Сообщений: n/a
По умолчанию 14.11.2004, 18:44

Я не спорю. А та прога была скорее слабым ответом на вопль о помощи, чем советом делать в том случае именно так.
В математике в некоторых задачах (например, комбинаторных) важно найти именно число решений, и не всегда для этого есть подходящая формула. Если при этом выручает компьютер, и лучше всего, в некоторых случаях, Пролог, почему этим не воспользоваться?
Головоломки здесь ни при чем. Иногда это частные случаи более общих задач. В учебном процессе (конечно, все должно быть в меру) их решение как без Пролога, так и с Прологом, в любом случае, как мне кажется, полезно, никому не повредит учиться думать головой.
Ответить с цитированием
  (#11 (permalink)) Старый
Anonymous
Guest
 
Сообщений: n/a
По умолчанию 14.11.2004, 19:22

Цитата:
Originally posted by Mnior
[b]<Те же грабли ...>
Если говорить конкретно, то меня все еще интересует головоломка про спички. И хотелось бы рассмотреть математическую сторону этой задачи. Наверняка здесь можно выявить самые общие закономерности в построении тех позиций и довести это даже до формул. Но для этого не мешало бы иметь перед глазами сами позиции при больших значениях первых компонентов троек. А для того, чтобы их иметь, надо сделать программу более эффективной - сейчас она их считает слишком долго или вообще отказывается это делать. Попробуйте строить их без компьютера - надолго и намного не хватит. С assertом программа пишется легко. И в игру можно играть. Но как это сделать без assertа? (крик души)
Ответить с цитированием
  (#12 (permalink)) Старый
Винитарх Винитарх вне форума
Специалист
 
Аватар для Винитарх
 
Сообщений: 7,988
Сказал(а) спасибо: 2
Поблагодарили 303 раз(а) в 303 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
По умолчанию 14.11.2004, 20:36

Mnior пишет:
Цитата:
Посему, СОВЕТУЮ ТАК НЕ ДЕЛАТЬ.
Во интересно?! А как по твоему делать?
По моему ничего другого кроме repeat-fail или findall нет.

Mnior пишет:
Цитата:
Т.к. это не логический подход, а императивный.
Ну так продемонстрируй логический подход.
Ответить с цитированием
Ads
  (#13 (permalink)) Старый
Anonymous
Guest
 
Сообщений: n/a
По умолчанию 16.11.2004, 21:50

Mnior его и продемонстрировал.
Жаль, что он больше здесь ничего не пишет
Ответить с цитированием
  (#14 (permalink)) Старый
Alison Alison вне форума
Member
 
Сообщений: 4,781
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
По умолчанию 20.11.2004, 22:42

Извините, пожалуйста, Mnior, я погорячилась. Совершенно напрасно
Ответить с цитированием
  (#15 (permalink)) Старый
Mnior Mnior вне форума
Member
 
Сообщений: 487
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 19.12.2002
По умолчанию 21.11.2004, 14:22

Цитата:
Originally posted by Alison
[b]В математике в некоторых задачах (например, комбинаторных) важно найти именно число решений, и не всегда для этого есть подходящая формула.
Согласен, но это не оправдание использования императифизма в в "ясных" задачах.
Скажем так: лучше повально использовать очевидную логику и на самый крайняк нелогичные элементы, чем повально путающий (нелогичное влияние одного на другое) императивизм.
Более того, на практике я и не встречал "таких" задач, где единственный метод, приносящий небывалый экспоненциальный прирост скорости, это императивные вставки. Обычно они приносили несколько процентов скорости, что для "таких" целей пофигу.

Подобного рода, как ваши, аргументы-ограничения в пользу скорости императивизма, в купе с свойствами целей и методов, практически не дают пересечений.

Примите сторону чистой логики, и все ваши страхи о скорости и эффективности, станут примером недальновидности.
Ответить с цитированием
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
помогите найти ошибку aska666 Prolog 2 13.04.2012 19:30
Помогите найти ошибку!!! tanuha_smile Pascal 2 23.02.2011 00:48
Не могу найти ошибку. Помогите найти и исправить... 111 Pascal 0 12.01.2011 16:30
Помогите найти ошибку! Владислав1 Pascal 6 11.01.2011 19:50
Помогите найти ошибку Женечка Pascal 0 06.12.2010 19:44
помогите найти ошибку kosmoskir Prolog 18 11.11.2010 19:03
Помогите найти ошибку! uncllebob Pascal 0 28.10.2009 13:18
ПОМОГИТЕ НАЙТИ ОШИБКУ Skorost5 Prolog 2 23.06.2008 22:36
Помогите найти ошибку (SWI) Avchent Prolog 5 04.09.2007 18:56
Помогите найти ошибку Kurdt Pascal 4 26.12.2006 00:11
Как найти первый корень по формуле: x[k+1] Masja Вопросы начинающих программистов 0 02.05.2005 20:56
помогите найти ошибку! asles PHP 1 06.01.2005 20:31



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов