Задать вопрос
@Dima239857

Как исправить программу на языке Prolog, чтобы устранить ошибку Free variable in expression?

У меня есть следующая проблема: в приведенном ниже коде вылетает ошибка: E;Test Goal, pos: 822, 707 Free variable in expression. Работаю на прологе 5.1. До добавления предиката с правилом рядом (правило 3) все работало, после добавления, указывает на ошибку в правиле 2-1 с предикатом занято. Подскажите как мне это устранить.

Predicates
% наименование, размер, нач строка, нач столбец, ориентация (горизонтально или вертикально)
nondeterm корабль (symbol, integer, integer, integer, symbol)

% первая и вторая координата клетки
nondeterm в_поле(integer, integer)
nondeterm занято(integer, integer)
nondeterm рядом(integer, integer)


Clauses
корабль (к41, 4, 2, 2, горизонтально).%ф1
корабль (к31, 3, 2, 7, вертикально) .%ф2
корабль (к32, 3, 2, 9, вертикально) .%ф3
корабль (к21, 2, 4, 2, вертикально) .%ф4
корабль (к11, 1, 7,  2, _) .%ф5
корабль (к12, 1, 7,  4, _) .%ф6
корабль (к13, 1, 7, 8, _ ) .%ф7
корабль (к14, 1,  9,  6, _) .%ф8

% Проверка, что клетка находится в рамках игрового поля
в_поле(X, Y):-
    X >= 1, X <= 10,
    Y >= 1, Y <= 10. %пр1

% клетка занята кораблем
занято(X,Y) :-
    корабль(_, Размер, X0, Y0, горизонтально),
    Y >= Y0, Y < Y0 + Размер, X = X0.%пр2-1

занято(X,Y) :-
    корабль(_, Размер, X0, Y0, вертикально),
    X >= X0, X < X0 + Размер, Y = Y0. %пр2-2

занято(X,Y) :-
    корабль(_, 1, X, Y, _). %пр2-3


% рядом с кораблем (включая диагонали)
рядом(X,Y) :-
    занято(X1,Y1),
    abs(X - X1) =< 1,
    abs(Y - Y1) =< 1. %пр 3



Goal
рядом(10, 5).%з2
  • Вопрос задан
  • 67 просмотров
Подписаться 1 Простой 2 комментария
Помогут разобраться в теме Все курсы
  • Нетология
    1C-программист: расширенный курс
    18 месяцев
    Далее
  • Академия Эдюсон
    Python-разработчик + ИИ
    9 месяцев
    Далее
  • ProductStar × РБК
    Профессия: Инженер по информационной безопасности
    9 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
opium
@opium
Просто люблю качественно работать
занято(X1,Y1) в правиле рядом вызывается с несвязанными X1 и Y1, а внутри сразу идёт Y >= Y0 с несвязанным Y — вот откуда Free variable. Предикат занято написан как чекер ("занята ли конкретная клетка?"), а не как генератор всех занятых клеток.

Фикс: добавь факты delta(-1). delta(0). delta(1). и перепиши рядом так, чтобы сначала вычислять координаты соседей (они будут связаны, т.к. X,Y в рядом(10,5) всегда bound), и только потом вызывать занято(X1,Y1) с уже связанными аргументами.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы