2012-06-13 2 views
4

Есть ли встроенный предикат или простой способ удалить из базы данных знаний пролог исходных файлов, с которыми уже проводились консультации? Я просмотрел справочное руководство и не нашел ничего, что могло бы это сделать.Swi Prolog, выгружая исходные файлы

ответ

4

Вы можете сделать это с этими процедурами, которые используют source_file/1 и source_file/2:

unload_last_source:- 
    findall(Source, source_file(Source), LSource), 
    reverse(LSource, [Source|_]), 
    unload_source(Source). 

unload_source(Source):- 
    ground(Source), 
    source_file(Pred, Source), 
    functor(Pred, Functor, Arity), 
    abolish(Functor/Arity), 
    fail. 
unload_source(_). 

unload_source/1 уничтожает все предикаты, определенные по имени файла входного источника. Будьте предупреждены, что это должен быть абсолютный путь.

unload_last_source/0 получит последнее имя файла и выгрузит его.

+1

Существует несколько вариантов реализации Пролога. OP не упоминает о системе Prolog, которую он использует. Это решение работает на SWI-Prolog. Он не будет работать в большинстве других компиляторов Prolog, которые не предоставляют встроенные предикаты source_file/1-2 и/или позволяют исключить статические предикаты. Решения, зависящие от конкретной реализации Prolog, лучше всего обозначаются как таковые. –

+0

@Paulo Moura: OP отметил вопрос как спецификацию SWI-Prolog. Вместо этого вместо этого следует отметить, что отмена работы без учета исходного файла ... – CapelliC

1

После того, как файл проконсультирован, он станет «неактуальным» для Пролога. Поэтому я думаю, что в целом ответ должен быть no. Но SWI-Prolog имеет богатый набор встроенных функций, который позволяет вам контролировать ваш программ. Например

?- [stackoverflow]. 

?- predicate_property(P, file('/home/carlo/prolog/stackoverflow.pl')). 
P = yield(_G297, _G298) ; 
P = now _G297 ; 
P = x(_G297) ; 
... 

?- abolish(yield/2). 
true. 

?- predicate_property(P, file('/home/carlo/prolog/stackoverflow.pl')). 
P = now _G297 ; 
P = x(_G297) ; 
... 

Заметим, что отменить не требует имя файла для работы, вы можете удалить предикаты, загруженные из других источников файлов.

clause, clause_property и erase должны дать больше контроля, но я получаю ошибку я не понимаю (это недокументированная) при попытке использовать Erase:

?- clause(strip_spaces(_G297, _G298),X,Y),erase(Y). 
ERROR: erase/1: No permission to clause erase `<clause>(0x29acc30)' 
0

, если вы знаете имя предиката, например, факт/2, вы можете использовать:

retractall(fact(_,_)). 
+0

применяется только к динамическим предикатам, то есть к тем, которые установлены с помощью 'assert', правильно? –

+0

Действительно, он применим только к динамическим предикатам, но их не нужно утверждать во время выполнения, также может быть объявлено в исходном файле. – Ihmahr