Расширение предложений Prolog с помощью forall / 2 - PullRequest
1 голос
/ 05 февраля 2020

Я использую clause/2 для преобразования некоторых предложений Prolog в компилятор. Мне нужно заменить заголовок каждого предложения на его тело, но clause/2 иногда не расширяет предложение так, как оно было изначально написано.

Здесь clause/2 расширяет demo(A,B) до \+ (call(A),\+call(B)), вместо того, чтобы расширять свое первоначальное определение:

:- use_module(prolog_to_minizinc).
:- initialization(main).

main :- 
        writeln(forall(A,B)),
        clause(demo(A,B),Clause),
        writeln(Clause).

demo(A,B) :-
    forall(A,B).

Есть ли другой способ расширить предложения, не изменяя предложения, которые включают forall/2?

1 Ответ

2 голосов
/ 06 февраля 2020

Нежелательное расширение цели forall/2 связано с загрузкой SWI-Prolog library(apply_macros) при запуске. Эта библиотека предоставляет код расширения для forall/2 и других предикатов. Узнать, как загружается library(apply_macros), нетривиально, так как установка флага verbose_autoload на true в файле ~/.config/swi-prolog/init.pl не печатает все библиотеки, которые автоматически загружаются при запуске. На моем ноутбуке используется текущая версия SWI-Prolog devel git (8.1.21-82-ge6e1d5376-DIRTY):

?- current_module(apply_macros).
true.

?- module_property(apply_macros, P).
P = class(library) ;
P = file('/Users/pmoura/lib/swipl/library/apply_macros.pl') ;
P = line_count(36) ;
P = exports([expand_phrase/2, expand_phrase/4]) .

?- source_file_property('/Users/pmoura/lib/swipl/library/apply_macros.pl', P).
P = modified(1547476368.0) ;
P = source(file) ;
P = module(apply_macros) ;
P = load_context(nb_set, '/Users/pmoura/lib/swipl/library/nb_set.pl':45, [imports([])]) ;
P = load_count(1) ;
P = number_of_clauses(52).

?- source_file_property('/Users/pmoura/lib/swipl/library/nb_set.pl', P).
P = modified(1547476368.0) ;
P = source(file) ;
P = module(nb_set) ;
P = load_context(solution_sequences, '/Users/pmoura/lib/swipl/library/solution_sequences.pl':46, []) ;
P = load_count(1) ;
P = number_of_clauses(13).

?- source_file_property('/Users/pmoura/lib/swipl/library/solution_sequences.pl', P).
P = modified(1574086719.0) ;
P = source(file) ;
P = module(solution_sequences) ;
P = load_context(editline, '/Users/pmoura/lib/swipl/library/editline.pl':59, []) ;
P = load_count(1) ;
P = number_of_clauses(49).

Файл editline.pl предоставляет удобную историю командной строки по умолчанию и другие услуги. Но если вы переключитесь на readline, добавив в свой файл ~/.config/swi-prolog/init.pl директиву:

:- set_prolog_flag(readline, readline).

Тогда вы получите:

?- [user].
|: a(A,B) :- forall(A,B).
|: % user://1 compiled 0.00 sec, 1 clauses
true.

?- listing(a/2).
% autoloading user:listing/1 from /Users/pmoura/lib/swipl/library/listing
a(A, B) :-
    forall(A, B).

true.

Это плохой обходной путь, но он может помочь вы.

...