К каким модулям неквалифицированное утверждение добавляет термин? - PullRequest
4 голосов
/ 30 апреля 2020
?- assertz(:- module(foo1, [f/1])).
true.

?- foo1:assertz(f(1)).
true.

?- foo1:f(1).
true.

?- foo2:f(1).
Correct to: "foo1:f(1)"? no
ERROR: Undefined procedure: foo2:f/1
ERROR: In:
ERROR:    [8] foo2:f(1)
ERROR:    [7] <user>

Имеет смысл для меня. Но тогда (с нуля) ....

?- assertz(:- module(foo1, [f/1])).
true.

?- assertz(f(1)).
true.

?- foo1:f(1).
true.

?- foo2:f(1).
true.    # Wait, what? foo2 doesn't appear in my program. Should fail?

?- frobnoz:f(1).
true.    # Also odd!

Но тогда ...

?- foo2:assertz(f(1)).
true.

?- foo2:f(1).
true.

?- frobnoz:f(1).
ERROR: Undefined procedure: frobnoz:f/1

Как f добавляется к foo2, когда я не упоминаю foo2. Почему frobnoz:f успешно во втором примере, но не в третьем?

Что такое модули? Я думал, что это пространства имен, но теперь я в замешательстве.

1 Ответ

3 голосов
/ 10 мая 2020

1-й вопрос:

Как f добавляется в foo2, когда я не упоминаю foo2.

Из Руководство по SWI-Prolog - Автозагрузка модуля section :

SWI-Prolog по умолчанию поддерживает автозагрузку из своей стандартной библиотеки. Автозагрузка подразумевает, что когда во время выполнения обнаруживается отсутствие предиката, выполняется поиск в библиотеке, и предикат лениво импортируется с помощью use_module / 2.

Вы можете go глубже , но в основном , когда модуль не определен явно, пролог ищет его и молча загружает его. Это поведение по умолчанию. Вы можете изменить его с помощью флаг автозагрузки .

2-й вопрос:

Почему frobnoz: f успешно во втором примере, но не в третьем?

Возможно, этот frobnoz:f можно найти как зависимость от модуля foo1, на который вы не ссылаетесь в третьем примере.

3-ий вопрос:

Что такое модули? Я думал, что это пространства имен, но теперь я в замешательстве.

Как Справочное руководство SWI-Prolog читает:

Модуль Prolog - это набор предикаты, которые определяют интерфейс publi c с помощью набора предоставленных предикатов и операторов. Модули Prolog определены стандартом ISO. К сожалению, стандарт считается провальным и, насколько нам известно, не реализован какой-либо конкретной реализацией Пролога. Синтаксис модульной системы SWI-Prolog получен из модульной системы Quintus Prolog. Модульная система Quintus была отправной точкой для модульных систем ряда основных систем Prolog, таких как SICStus, Ciao и YAP. Основные примитивы модульной системы SWI-Prolog отличаются от упомянутых систем. Эти примитивы допускают несколько модулей в файле, иерархические модули, эмуляцию интерфейсов других модулей и т. Д. c. ( source )

В системах класса c Prolog все предикаты организованы в одном пространстве имен, и любой предикат может вызывать любой предикат. [...] Модуль Prolog инкапсулирует набор предикатов и определяет интерфейс. Модули могут импортировать другие модули, что делает зависимости явными. Учитывая явные зависимости и четко определенный интерфейс, становится намного проще изменить внутреннюю организацию модуля, не нарушая общее приложение. ( source )

Обычно имя модуля совпадает с именем файла, которым он определен без расширения имени файла, но это именование не применяется. Модули организованы в едином и плоском пространстве имен, поэтому имена модулей следует выбирать с некоторой осторожностью, чтобы избежать конфликтов. Как мы увидим, типичные приложения системы модулей редко используют имя модуля явно в исходном тексте. ( источник )

...