2017-01-09 5 views
0

J'ai cette portion de code comme cas de base dans un prédicat récursif.Pourquoi prolog ne reconnaît pas les arguments dans une requête?

riduci_lista_valori([[V, N]],m_var,Lr):- 
    member(V, m_var), 
    Lr =[N]. 

Le problème est que quand je joue ma requête, il ne correctement unifie pas les arguments du prédicat avec ses paramètres. Vu le code, ma requête est: riduci_lista_valori([[a, 5]], [c,e], F). Et je m'attends à ce que Prolog retourne F = [5] Débogage du code semble qu'il ne reconnaît pas correctement les arguments car il ne s'unifie pas comme: V = a, N = 5m_var = [c,e] mais il donne: 1 = [[a, 5]] et 2 = [c, e].

Alors que si je vous invite: [[V, N]] = [[a,5]]. il fait la bonne unification: V = a, N = 5.

Qu'est-ce que je fais mal? Je vous remercie!

Répondre

4

Pour détecter les causes de l'échec dans Prolog, utilisez débogage déclaratif:

Ajouter les définitions suivantes à votre programme:

:- op(920,fy, *). 
*_. 

Maintenant, vous pouvez utiliser (*)/1-généraliser loin objectifs spécifiques .

Par exemple:

 
riduci_lista_valori([[V, N]], m_var, Lr) :- 
     *member(V, m_var), 
     *Lr =[N]. 

Même avec cette version beaucoup plus générale, nous obtenons:

 
?- riduci_lista_valori([[a, 5]], [c,e], F). 
false. 

Cela signifie que si vous vous attendez à la requête réussir à tout, vous besoin de encore généraliser votre programme. Voir ce qui reste en fait du programme:

 
riduci_lista_valori([[V, N]], m_var, Lr) :- true. 

Cet extrait est déjà trop spécifique. Généralisons comme ceci:

 
riduci_lista_valori([[V, N]], Var, Lr) :- true. 

Maintenant, la requête réussit:

 
?- riduci_lista_valori([[a, 5]], [c,e], F). 
true. 

Ainsi, ce second argument de votre tête de l'article est un bon candidat pour une inspection approfondie!

Peut-être que vous vouliez dire utiliser une variable au lieu de l'atome m_var?

+0

Merci pour votre réponse, j'ai appris quelque chose de nouveau à propos de débullage déclaratif. Mais votre dernière ligne a sauvé ma nuit :) –

+0

s (X), quelle idée géniale! –

+1

Pourriez-vous inclure une référence qui explique \ expand 'debugging déclaratif' en ce qui concerne Prolog; en particulier l'utilisation de 'op (920, fy, *).' C'est une bonne technique que je voudrais intégrer dans ma boîte à outils Prolog. Si vous souhaitez que ce soit une question distincte, il suffit de demander. Peut-être que cela devrait être un tag avec des références comme [tag: failure-slice] –