2012-05-25 1 views
1

Récemment, j'ai essayé le livre "Building Expert Systems in Prolog" qui est disponible gratuitement au http://www.amzi.com/ExpertSystemsInProlog.Native Prolog Shell

Il existe un code appelé shell natif à l'annexe avec une base de données d'identification des oiseaux. Le problème est que, après consultation avec la coquille et en cours d'exécution:

principal.

charge.

résoudre.

Il demande "narines: externe_tubulaire?"

Si vous répondez non, un débordement de pile se produit. Le problème est probablement à la section coup:

prove(true,_) :- !. 
prove((Goal,Rest),Hist) :- 
    prov(Goal,[Goal|Hist]), 
    prove(Rest,Hist). 
prove(Goal,Hist) :- 
    prov(Goal,[Goal|Hist]). 

prov(true,_) :- !. 
prov(menuask(X,Y,Z),Hist) :- menuask(X,Y,Z,Hist), !. 
prov(ask(X,Y),Hist) :- ask(X,Y,Hist), !. 
prov(Goal,Hist) :- 
    clause(Goal,Body), 
    prove(Body,Hist). 

Quelqu'un peut s'il vous plaît aidez-moi s'il vous plaît? Toute aide est grandement appréciée.

code complet de la coquille: http://www.amzi.com/ExpertSystemsInProlog/code/native/native.pro

Code complet pour la base de données: http://www.amzi.com/ExpertSystemsInProlog/code/native/birds.nkb

J'utilise Prolog SWI.

+1

Vous utilisez l'exemple de code écrit pour Amzi! Prolog avec l'interpréteur SWI-Prolog, donc ma première pensée est qu'il y a une incompatibilité de syntaxe. Cependant, l'erreur que vous signalez (débordement de pile) n'aide pas à déterminer où le code doit être corrigé. Peut-être [les installations de débogage dans SWI-Prolog] (http://www.swi-prolog.org/pldoc/man?predicate=trace/0) devraient être votre prochaine étape. Le [traceur graphique SWI-Prolog] (http://www.swi-prolog.org/gtrace.html) nécessite la console XPCE. – hardmath

+0

La distribution Logtalk actuelle (http://logtalk.org/) inclut un port d'Amzi! système expert d'identification des oiseaux. Vous pouvez (également) parcourir le code source ici: http://trac.logtalk.org/browser/trunk/examples/birds Vous pouvez exécuter le port en utilisant la plupart des compilateurs Prolog (y compris SWI-Prolog) comme Compilateur dorsal Logtalk. –

Répondre

1

Je trouve que le problème est ici:

prove((Goal,Rest),Hist) :- 
    prov(Goal,[Goal|Hist]), 
    prove(Rest,Hist). 
prove(Goal,Hist) :- 
    prov(Goal,[Goal|Hist]). 

Depuis SWI-Prolog permet à la tête ((x, y, z), [ h]) pour correspondre au deuxième prédicat de preuve, d'une manière ou d'une autre dans le processus d'inférence, le test (Goal, Hist) est déclenché, ce qui provoque l'apparition de la boucle infinie. Il m'a fallu 8 heures pour analyser la trace. Par conséquent, pour résoudre le problème, nous avons besoin d'une coupure à placer au début de la preuve ((But, Rest), Hist).Le code devrait ressembler à ceci:

prove((Goal,Rest),Hist) :- 
    !, 
    prov(Goal,[Goal|Hist]), 
    prove(Rest,Hist). 
prove(Goal,Hist) :- 
    prov(Goal,[Goal|Hist]). 
1

Le problème en effet se manifeste par

prove(Goal,Hist) :- 
    prov(Goal,[Goal|Hist]). 

prov(Goal,Hist) :- 
    clause(Goal,Body), 
    prove(Body,Hist). 

clause(:Head, ?Body) devrait être vrai si Head peut être unifiée avec une tête de clause et Body avec le corps de l'article correspondant. Malheureusement, pour tout programme SWI-Prolog croit clause(call(X), call(X)) pour être vrai. Cela signifie que clause(call(nostrils(external_tubular)), X) réussit et que prove est appelé, ce qui à son tour appelle prov avec un second argument croissant. Comme clause/2 est un prédicat statique, son contenu ne peut pas être modifié avec retractall ou abolish. Les solutions possibles sont:

  1. Report a bug to SWI developers
  2. Remplacer clauses birds.nkb par quelque chose comme myclause et se réfèrent à myclause dans la mise en œuvre de la coquille.
  3. Regardez d'autres dialectes Prolog ...
+0

Merci alexander pour l'effort. J'ai ajouté la cause réelle comme solution. Je vais attribuer la prime dans les 9 heures. Je suis autorisé à le faire dans les prochaines 9 heures. –

+0

Je pense qu'ajouter '\ + Body = Goal' après' clause (Goal, Body) 'devrait résoudre le problème' de la clause (appel (X), appel (X)) '. –

0

Vous pouvez également corriger en ajoutant le prédicat prov((_,_),_) :- !, fail. juste au-dessus de la section:

prov(true,_) :- !. 
prov(menuask(X,Y,Z),Hist) :- menuask(X,Y,Z,Hist), !. 
prov(ask(X,Y),Hist) :- ask(X,Y,Hist), !. 
prov(Goal,Hist) :- 
    clause(Goal,Body), 
    prove(Body,Hist).