2013-05-16 1 views
-1

Je suis en train d'étudier Prolog DCG grammaire * et ** arbre d'analyse syntaxique sur le livre Ivan Bratko: « Programmation pour l'intelligence artificielle »Certains doutes liés sur la façon dont fonctionne un prédicat sens qui interprète l'arbre d'analyse syntaxique d'une grammaire DCG en Prolog

Je trouve quelques difficultés avec l'exemple suivant qui fournit une grammaire DCG qui crée une arborescence d'analyse à partir d'une chaîne appartenant à la langue définie.

La langue définie est une liste de mouvements d'un bras robotisé qui peut être seulement deux types: up et vers le bas si [haut, haut, bas, haut, haut] appartient à la langue définie par ma grammaire DCG.

Le programme fournira également un sens/2 prédicat qui interprète l'arbre d'analyse syntaxique associée à une certaine chaîne et que signifie la distance parcourue par le bras du robot (considérant qu'il est associé à un déplacement vers le haut la valeur + 1, et la valeur -1 pour un mouvement vers le bas)

Ainsi, par exemple pour la liste [up, haut, bas, haut, haut], le signifie/2 prédicat calculer une distance de 3

Voici le code de mon exemple (travail bien):

move(move(Step)) --> step(Step). 
move(move(Step, Move)) --> step(Step), move(Move). 

step(step(up)) --> [up]. 
step(step(down)) --> [down]. 

/* Take the parse tree of a string that belong to the language defined by the DCC grammar and 
    calculate the total distance whereas that an up move give a +1 distance and a down move 
    give -1 distance 
*/ 
meaning(move(Step, Move), Dist):- 
            /* Calculate the distance given by the current step node 
            (which can be +1 or -1) */ 
        meaning(Step, D1), 
        /* Calculate the distance given by the current moove node 
            (which must be calculated recursively on a subtree having 
             a moove node as root */ 
        meaning(Move, D2), 
        /* The final distance series of moves is the distance of the 
            current step + the distance diven from the moves in the 
            moove subtree */ 
        Dist is (D1 + D2). 

meaning(step(Step), Dist):- meaning(Step, Dist). 
meaning(move(Step), Dist):- meaning(Step, Dist). 

% step(up) means that the distance is +1 
meaning(step(up), 1). 

% step(down) means that the distance is -1 
meaning(step(down), -1). 

J'ai donc le sens /2 prédicat qui prennent un arbre d'analyse syntaxique et de calculer la distance totale des mouvements.

So I have 2 CAS DE BASE que rappresent la valeur de distance associée à un mouvement unique (à une étape), qui peut être une pour la mise pas et -1 pour l'étape vers le bas:

meaning(step(up), 1). 
meaning(step(down), -1). 

le sens/2 prendre un arbre d'analyse syntaxique qui, tel que défini par la grammaire DCG, ont un mouvement nœud en tant que root: cette racine aura un enfant gauche qui est une étape noeud (il est donc un déplacer, donc il a une distance spécifique +1 ou -1 qui lui est associée) et un enfant droit qui est un déplacer noeud (il rappresent un autre sous-arbre)

Ainsi, la distance totale est la somme de la distance de l'étape en cours qui est +1 ou -1 (l'enfant gauche de l'mouvement racine courant) + le distance dans le sous-arbre droit.

Je pense que cela est correct et cela est assez clair pour moi

La chose que je ne comprends pas ce que représente pour moi ces deux prédicats dans le code:

meaning(step(Step), Dist):- meaning(Step, Dist). 
meaning(move(Step), Dist):- meaning(Step, Dist). 

je peux pas les coller dans mon raisonnement :-(

+1

Était-il vraiment nécessaire de copier toute la question et réserver la section pour obtenir de l'aide sur ces quatre lignes de code? Aussi, avez-vous essayé juste _running_ le code? C'est évident ce que ces règles font: elles vous permettent d'appeler 'meaning/2' sur des faits enveloppés directement à partir du DCG. Ils déplient simplement la couche structure supplémentaire. –

Répondre

2

Nous utilisons ces règles comme si,

4 ?- phrase(move(X), [up,up,down,up,up]). 
X = move(step(up), move(step(up), move(step(down), move(step(up), 
     move(step(up)))))) ; 
false. 

5 ?- meaning($X,N). 
N = 3 ; 
false. 

Le terme produit est très imbriqué:

move(step(up),       % move/2: step/1 , 
    move(step(up),      % move/2: step/1 , 
      move(step(down),    %  move/2: step/1 , 
       move(step(up),   %  move/2: step/1 , 
        move(step(up)))))) %   move/1: step/1 . 

Le code que vous posez des questions sur, bandes loin le functors des termes composés, se rendre à la « viande » de celui-ci, à savoir up ou down atome arguments:

(2)meaning(step(Step), Dist):- meaning(Step, Dist).

« pour trouver le « » sens « » d'un terme composé unaire step(X), est le même que pour trouver le « » sens « » de X ".

(3)meaning(move(Step), Dist):- meaning(Step, Dist).

"pour trouver le '' sens '' d'un terme composé unaire move(X), est le même que pour trouver le '' sens '' de X".

(4) cas de base: '' sens '' est donnée à titre 1 ou -1 pour up ou down atomes.

meaning(step(up), 1).     % clashes with rule (2) 
meaning(step(down), -1).     % clashes with rule (2) 

(1) Et la principale affaire porte sur des termes composés binaires avec le foncteur move:

meaning(move(Step, Move), Dist):- 
    meaning(Step, D1), 
    meaning(Move, D2), 
    Dist is (D1 + D2). 

move/2 est une version personnalisée de la liste (non vide), '.'/2, en fait:

1 ?- write_canonical([1,2,3]). 
'.'(1,'.'(2,'.'(3,[]))) 
true. 

2 ?- write_canonical([step(up),step(down),step(up)]). 
'.'(step(up),'.'(step(down),'.'(step(up),[]))) 
true. 

Et meaning/2 est un fold.

+0

tnx tellement !!! Maintenant c'est clair. – AndreaNobili

+0

Je m'excuse, si parfois je mets une longue question mais sinon j'ai peur de ne pas être clair dans les questions – AndreaNobili

+2

@AndreaNobili vous êtes venus bien, commencer à croire vos capacités plus et * paraphraser * et * résumer *; encore plus, laissez le code Prolog parler pour lui-même en mode. :) –

Questions connexes