2011-12-29 12 views
6

Napisałem poniższy prosty kod i spodziewam się, że kiedy piszę "męski", ten kod pyta mnie raz "czy to mężczyzna?" a jeśli wprowadzę "Nie", to napisz na ekranie "ona jest płci żeńskiej".Chcę stworzyć dynamiczne fakty w prologu

male :- (print('is it male ? '),read(yes)) -> true; asserta(not(male)),female. 
female:- not(male),print('she is female'). 
not(P) :- (call(P) -> fail ; true) . 

ale ten kod jest następujący błąd:

uncaught exception: error(permission_error(modify,static_procedure,not/1),asserta/1); 

błąd w SWI Prolog jest:

ERROR: asserta/1: No permission to modify static_procedure `not/1' 
+1

Nie/1 to wstępnie zdefiniowana procedura statyczna. Zastanów się nad zmianą nazwy na coś innego. Również nie wydaje Ci się to właściwe, co robisz. – gusbro

Odpowiedz

7

Jak gusbro powiedział, nie/1 jest predefiniowanym Procedura statyczna (i dlatego nie jest dobrym pomysłem użycie tej samej nazwy). Jednakże, nie jest to powód, dla którego pojawia się błąd w swi-prolog jak można zastąpić standardową definicję:

?- assert(not(42)). 
true. 

?- not(42). 
true. 

problemem jest to, że już nie/1 zdefiniowany w kodzie, a kiedy nie deklaruj predykat jawnie jako dynamiczny, swi-prolog przyjmie, że jest statyczny i nie pozwoli ci go zmienić.

Można zadeklarować ją jako dynamiczny, wstawiając ten wiersz w kodzie:

:-dynamic(not/1). 

myślę, że to nie rozwiąże problemu w innych implementacjach Prolog (np GNU Prolog), jak mówi komunikat o błędzie permission_error(modify,static_procedure,not/1) ; w każdym przypadku zaleca się zmianę nazwy.

Przy okazji, byłoby prostsze i czystsze, aby po prostu sprawdzić, co jest argumentem i wydrukować odpowiedni komunikat. Jeśli jednak chcesz stworzyć coś bardziej złożonego (używając może stanu), możesz użyć zmiennych globalnych, ponieważ są one bardziej wydajne, które zapewniają assert/retract.