Error: Free variable are not allowed in ‘not’ or ‘retractall’

      Комментарии к записи Error: Free variable are not allowed in ‘not’ or ‘retractall’ отключены

Главная Форумы Программирование Помощь с решением задач на Prolog Общие вопросы Error: Free variable are not allowed in ‘not’ or ‘retractall’

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

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

    questioner
    Участник

    В Visual Prolog получаю ошибку:

    E;Test_Goal, pos: 274, 704 Free variable are not allowed in ‘not’ or ‘retractall’

    Хотя, в SWI Prolog этот же код ошибок не выдает. Как решить проблему? Написал минимальный пример кода, демонстрирующего ошибку:

    DOMAINS
      name = string
      score = real
      course = integer
    PREDICATES
      nondeterm student(name, course, score)
    CLAUSES 
      student("petrov", 1, 5.0).
      student("sidorov", 2, 3.2).
      student("ivanov", 1, 4.2).
    GOAL    
      %student("petrov", 1, _Score).
      NOT(student("petrov", 2, _Score)).

    Я описал трех студентов. Цель student("petrov", 1, _Score). проверяет что Петров учится на первом курсе, а цель NOT(student("petrov", 2, _Score)). — что он учится не на втором курсе. Первая цель отрабатывает без ошибок, но вторая даже не компилируется.

  • #3475

    Проблема заключается в том, что Visual Prolog не разрешает использование свободных переменных внутри операторов NOT и retractall. В вашем коде такой переменной является _Score, т.к. на момент выполнения выражений никакое значение ей не присвоено.

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

    student("petrov", Course, _Score),
    NOT(Course = 2).

    Во-вторых, можно добавить вспомогательный предикат, который будет перебирать студентов без учета их оценки (которая и создает свободную переменную) и использовать его в выражении NOT:

    PREDICATES
      nondeterm student(name, course, score)
      nondeterm name_course_student(name, course)
    CLAUSES 
      % ... your students
      name_course_student(Name, Course):-
      	student(Name, Course, _Score).
    GOAL    
      NOT(name_course_student("petrov", 2)).

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