Inform 6 : Parseur idiot

Bon, comme prévu c’était une bêtise… Je cherche un autre moyen de modifier les choses dans French.h ou FrenchG.h.

Note : pour le problème récurrent de ce style :

Le problème vient du fait que « les » peut être à la fois un article (the) ou un pronom (them) qui fait référence à un objet (ici : les poireaux).
C’est « les » comme dans « regarde-les » ou « les regarder ».
Dans le cas présent, les est un article pour moi qui le tape, mais pour le parser le considérer comme un pronom lui donne un meilleur score.

Si on pouvait faire en sorte que le pronom les n’en soit un que lorsqu’il n’est pas suivi d’autres mots, cela pourrait aider.

Par ailleurs « regarde les » a un sens mais « regarder les » non. C’est sûrement très difficilement faisable, mais dans le cas où le verbe est n’est pas un impératif « les » ne devrait être considéré comme pronom que s’il est placé devant le verbe.

Est-ce qu’il faudrait utiliser « -les » comme identifiant pour le pronom « les » pour essayer de dépêtrer le parseur de ce problème ?

Otto, JL, JB, Adrien, vous auriez une opinion sur le sujet ?

Voilà une correction imparfaite et un peu violente : j’ai tout simplement viré le la les de la définition des pronoms (j’ai remis -la, -les -le à la place).

D’abord (ligne 148 environ)

      ! Object pronouns
      '-le'    $$100000100000                    NULL
      '-la'    $$010000010000                    NULL
      '-les'   $$000110000110                    NULL
!      '-lui'   $$110000110000                    NULL
!      '-leur'  $$000110000110                    NULL	! tirets enlevés
!      'le'    $$100000100000                    NULL	! en espérant que l'article le/la/les ne vienne pas interférer
!      'la'    $$010000010000                    NULL	! (Le parser a l'air de se débrouiller.)
!      'les'   $$000110000110                    NULL
      'lui'   $$110000110000                    NULL ! dans "donne-lui", "lui" est m ou f
      'leur'  $$000110000110                    NULL

Et plus loin (ligne 185 environ)

!      'son'    $$100000100000    POSSESS_PK      '-lui'
!      'sa'     $$010000010000    POSSESS_PK      '-lui'
!      'ses'    $$000110000110    POSSESS_PK      '-lui'
      'leur'   $$110000110000    POSSESS_PK      '-les'
      'leurs'  $$000110000110    POSSESS_PK      '-les'	! tirets enlevés 
      'son'    $$100000100000    POSSESS_PK      'lui' 
      'sa'     $$010000010000    POSSESS_PK      'lui' !*! remplacer par "luy" ?
      'ses'    $$000110000110    POSSESS_PK      'lui' !*! 2e colonne : mettre m et f ?
!      'leur'   $$110000110000    POSSESS_PK      'les'
!      'leurs'  $$000110000110    POSSESS_PK      'les' 

Grâce aux traitements de la fonction LanguageToInformese, une commande comme « le prendre » fonctionne toujours car transformée en « regarder lui ».

En revanche « regarde-le » ne fonctionne pas encore. Il faudrait un traitement spécifique pour ces cas là.

Je suis allé plus loin que je ne le pensais dans mes modifications et j’ai également modifié la fonction LanguageToInformese. J’espère ne pas avoir fait de grosse boulette.

J’ai remplacé ceci :

    !  jadis, insertion d'un espace avant chaque tiret et après chaque apostrophe 
    !  depuis la 2.1, suppression des tirets et insertion d'un espace après chaque apostrophe
    for (i=WORDSIZE:i<WORDSIZE+NbChars():i++) {
         if (buffer->i == '-') buffer->i=' ';
         if (buffer->i == ''') LTI_Insert(i+1, ' ');
    }
    Tokenise__(buffer,parse);

par cela :

    !  Si le dernier mot de la phrase est "le" ou "la" ou "les",
    ! les remplacer par "-le" ou "-la" ou "-les"
    ! (en espérant que la condition n'est pas trop "large")
    i = NbMots()-1;
    at = PositionMot(i); ! position du mot numéro i dans buffer
    if (Mot(i) == 'les') LTI_Insert(at, '-');
    if (Mot(i) == 'le') LTI_Insert(at, '-');
    if (Mot(i) == 'la') LTI_Insert(at, '-');
    Tokenise__(buffer,parse);

    !  Premier passage : insertion d'un espace avant chaque tiret et après chaque apostrophe 
    for (i=WORDSIZE:i<WORDSIZE+NbChars():i++) 
    {
        if (buffer->i == '-') LTI_Insert(i++, ' ');
        if (buffer->i == ''') LTI_Insert(i+1, ' ');
    }
    Tokenise__(buffer,parse);

    ! Deuxième passage
    ! Suppression des tirets en début de mot, sauf pour les mots
    ! -les, -la et -le
    ! problème : il va rester 2 espaces entre deux mots si un tiret est viré (c'est grave ?)
    for (i=0:i<NbMots():i++)
    {
        word = Mot(i);
        at = PositionMot(i); ! position du mot numéro i dans buffer
        if (buffer->at == '-')
        {
            if (word~='-les' && word~='-le' && word~='-la')
            {
                buffer->at = ' ';
            } 
        }
    }
    Tokenise__(buffer,parse);

Maintenant :

  • regarde-le (ou -la ou -les) fonctionne
  • regarde le (ou la ou les) aussi à condition que le/la/les soit le dernier mot de la phrase.
  • une phrase comme « prends la pomme puis mets-la dans le sac » est OK, mais s’il manque le tiret de « -la » mon implémentation ne suffira pas car elle n’est pas en bout de phrase et ‹ la › restera un article et non un pronom. Il faudrait en fait ajouter le tiret devant le/la/les si le mot est en fin de groupe nominal (c’est ça le terme exact ?) mais je ne sais pas faire.
  • dans les messages d’erreur, on a droit à ça par exemple (améliorable, donc) :

J’attends vos remarques, pour me dire que j’ai tout cassé, que j’ai fait trop compliqué ou que cela vous semble aller dans le bon sens.

je vais regarder si je peux modifier mes bibliothèques avec cela. Cela ne touche que french.h c’est cela ?

Oui cela ne touche que french.h

Cela tente de résoudre l’ambiguité entre « le/la/les » pronom et « le/la/les » article.

Je ne sais pas si cela résoud le problème de « ouvrir malle » => « je n’ai compris que: ouvrir julie » et le problème de « ouvrir le portail » => « Je n’ai compris que : ouvrir Galina » mais je serais intéressé si JB pouvait tester ces cas de figure, et également si d’autres peuvent tester sur leurs jeux voir s’ils remarquent des problèmes (ou simplement inspecter mon code pour remarquer de grosses bêtises que j’aurais pu faire).

Salut Stormi, et désolé de n’avoir pu répondre plus tôt. Tu es effectivement sur la bonne voie, et je signale que le commentaire angoissé (mais hélas prémonitoire) « tirets enlevés en espérant que l’article le/la/les ne vienne pas interférer » est très probablement de moi : dans les versions précédentes il y avait un tiret devant le/la/les. Je ne sais plus pourquoi exactement j’avais changé ceci mais c’est très probablement lié à l’usage d’autres formes que l’infinitif, des problèmes subtils apparaissant dans des expressions comme « donne-les » (ou, pire, « donne les ») alors que « les donner » en posait moins.

Au fond, cet ajout des autres formes que l’infinitif apporte peu de bienfaits (ce n’est pas suffisant pour rendre le jeu attractif pour plus de monde), tout en ajoutant des bugs.

J’avais en effet remarqué ce commentaire et il m’a d’ailleurs aidé à confirmer mon idée. Est-ce que tu as vu la suite des commentaires de ce fil, où j’ai atteint une solution presque acceptable en modifiant LanguageToInformese, à part sur un cas particulier ?

Au sujet des formes autres que l’infinitif, en les utilisant pour tester (notamment l’impératif 2e personne du singulier), je me suis surpris à apprécier la « pêche » que cela donne aux commandes :slight_smile:. Je ne pense pas que cela soit vraiment inutile, donc.
Par ailleurs, là où l’impératif serait vraiment nécessaire (2e personne siingulier surtout, mais aussi 2e pluriel parfois), c’est dans les ordres donnés aux personnages :

« > conducteur, sors » n’est pas reconnu alors que « > conducteur, sortir » l’est.
Ce n’est probablement pas simple à gérer, mais si quelqu’un a une piste…

demander au conducteur de sortir

:wink:

(message en double ; voir le suivant)

En fait voici un extrait de French.h de la dernière version, la version de travail 2.1.1 du 15 octobre 2004 avec « la gestion des pronoms améliorée » :

[code]Array LanguagePronouns table

! word possible GNAs connected
! to follow: to:
! a i
! s p s p
! mfnmfnmfnmfn

  ! Object pronouns
  '-le'    $$100000100000                    NULL
  '-la'    $$010000010000                    NULL
  '-les'   $$000110000110                    NULL
  '-lui'   $$110000110000                    NULL
  '-leur'  $$000110000110                    NULL	! tirets remis

! ‹ le › $$100000100000 NULL ! car l’article le/la/les vient parfois interférer
! ‹ la › $$010000010000 NULL ! par exemple « mange la pomme » est compris comme « mange-la » si « pomme » est inconnu, d’où des messages d’erreur troublants pour le joueur
! ‹ les › $$000110000110 NULL
! ‹ lui › $$110000110000 NULL ! dans « donne-lui », « lui » est m ou f
! ‹ leur › $$000110000110 NULL
[/code]

Le commentaire est : « tirets remis car l’article le/la/les vient parfois interférer ; par exemple « mange la pomme » est compris comme « mange-la » si « pomme » est inconnu, d’où des messages d’erreur troublants pour le joueur ». Le bug n’existait donc peut-être déjà plus dans la version 2.1.1. Bizarre que je n’aie pas vu cela plus tôt, il doit y avoir un truc.

(sinon effectivement LanguageToInformese est l’autre passage où intervenir)

il faudrait donc réussi à mettre en commun ta version (non publiée) 2.1.1. et les améliorations de Stormi. Ensuite je pourrais reprendre cela pour le transformer en version compatible Inform 7.

Il faudra d’abord améliorer mes améliorations :slight_smile:

En fait la version « de travail » 2.1.1, même si elle n’est pas publiée sur IF Archive, est disponible sur la page d’accueil de jlpo.free.fr (« news » du 15/10/04).

Donc effectivement il s’agit de comparer les deux versions qui sont certainement très proches.

Je me souviens d’avoir, dans le cas de l’impératif, imposé au joueur l’usage du tiret (sinon trop d’ambiguités à résoudre) sauf dans certains cas simples, non ambigus, qui sont l’occasion de conseiller au joueur d’employer les tirets les fois suivantes.

Ce qui manque plus ou moins, c’est un fichier de test (par exemple un fichier comme aventure.rec utilisant les cas souhaités), afin de vérifier que tout fonctionne à peu près aussi bien. J’avais essayé à une époque d’automatiser tant bien que mal ces tests, mais sur Windows aucun interpréteur ne permettait vraiment de maîtriser l’entrée et la sortie du programme. Je me contente donc de vérifier que le score maximal est atteint quand je lance manuellement le replay. En tout cas la mise au point de tests (de non régression ?) s’imposait pour limiter les bugs qui ont tendance à apparaître quand on en fait disparaitre d’autres. Inform 7 inclue d’ailleurs un outil de test (hélas difficile à séparer du reste) qui manquait cruellement jusque là, je trouve.

Bref, Stormi, si tu as ces modifications encore en tête, je t’invite (si le coeur t’en dit, bien sûr) à les comparer à celles de la version 2.1.1 (où une trentaine de lignes de code dans LanguageToInformese sont liées à cette histoire de tirets). Sinon je m’y plongerai un de ces jours (pas trop ces temps-ci, d’autant que d’ici un jour ou deux je serai de nouveau hors-ligne pendant plusieurs semaines). Sinon la 2.1.1 est disponible, donc, si quelqu’un veut s’en inspirer. (une autre version de travail (mais non-disponible) existe, mais ses modifications étaient vraiment minimes, contrairement à la version 2.1.1)

Oui je les ai en tête et un peu plus haut dans ce fil (c’est une forme d’archivage :slight_smile:). Je vais donc regarder la version 2.1.1.

Alors, j’ai regardé, et en effet la version 2.1.1 améliore grandement la gestion des pronoms. Le diagnostic était le même (ambiguïté entre certains pronoms et articles), mais la solution de JL est bien plus élaborée que ma tentative.

J’ai testé un peu, et cela fonctionne bien. J’aurais simplement une modification à apporter à FrenchG.h :

  • ajouter la grammaire « creature noun » et « noun creature » au verbe ‹ donner ›. (sinon, on ne peut pas dire « lui donner le truc » ou « donne-lui le truc ».

Il y a également une petite correction à apporter là :

	if ((NbMots()==3)&&(Mot(1)=='le'or'la'or'les'or'-le'or'-la'or'-les')&&(Mot(2)=='lui'or'leur')) { ! "donne le lui" ou "donne-le lui" devient "donne-le-lui"
		if (Mot(1)=='le'or'la'or'les') LTI_Insert(PositionMot(1), '-');
		LTI_Insert(PositionMot(2), '-');
		print "[Mettez toujours un trait d'union entre chaque pronom et le verbe à l'impératif !]^";
	}

Il faut rajouter un « Tokenise__(buffer,parse); » dans le premier if, sinon « donne la lui » est transformé en « donne -la- lui » au lieu de « donne -la -lui ».

Par ailleurs, si les tests montrent que l’absence de tiret devant « le/la/les/lui… » ne pose pas de problème majeur, je suis pour les tolérer silencieusement, sans avertissement, ou au moins rendre l’avertissement plus sympa « Pour une meilleure compréhension de vos commandes, mettez un trait d’union entre chaque pronom et le verbe à l’impératif ».

En revanche, il est impossible de taper « donne-le-lui » et d’être compris, car « le » et « lui » ont toujours la même valeur. Il n’y a pas vraiment de reconnaissance fine de « le » désigne un « noun » et lui désigne un « creature », dans ce contexte. Problème soulevé, pas de solution pour l’instant de ma part :slight_smile:

Merci beaucoup pour tes remarques et modifications, je les note pour plus tard (ce qui n’empêche personne d’en tenir déjà compte bien sûr).

Le conseil donné par le jeu est effectivement un peu raide. Je comptais plutôt commencer par « Conseil : … » (plus court et lisible). Là où ce conseil pourrait se justifier, c’est si par la suite une commande comme « donne le à untel » donne une réponse trop mauvaise.

« donne-le-lui » ne peut donc pas marcher ? je ne sais plus si j’avais testé ce cas.

Peut-être que l’emploi des pronoms (et avec autre chose que l’infinitif, en plus) est assez rare, d’autant que tous les jeux ne le permettent pas. Donc cet emploi exceptionnel perturbe les cas courants, notamment ceux où l’article le/la/les est utilisé (quoique, est-ce si courant d’utiliser l’article ? c’est peut-être l’inverse).

Je ne sais pas si c’est rare, mais personnellement j’utilise toujours des articles pour que ce que je tape soit plus proche de la langue naturelle (comme je tape avec 9 doigts cela ne me ralentit pas), et j’utilise les pronoms pour aller plus vite, en particulier dans la situation suivante :

quand je peux taper une phrase telle que « le prendre puis le manger » ou « prends-le puis mange-le » (dans ces situations je regrette d’ailleurs que « et » ne puisse pas être utilisé à la place de puis…) j’ai vraiment l’impression que le parser n’est pas trop bête, qu’il a des notions plus puissantes qu’un simple « verbe objet »
C’est ça, la reconnaissance des pronoms, on n’y pense pas tout de suite quand on joue, habitué à des syntaxes simplistes, mais quand on le découvre c’est un peu la cerise sur le gateau du parseur :slight_smile:

Pour moi, il est donc important que à la fois les articles et les pronoms soient gérés d’une manière la plus satisfaisante possible.

au fait JL je ne sais pas si tu as vu, mais j’ai ouvert un fil dédié à la recherche d’améliorations pour la bibliothèque : ifiction.free.fr/forumBB/viewtop … highlight=

Effectivement je n’avais pas vu, tu fais bien de me le signaler. La fonction « Voir les derniers messages depuis votre dernière visite » a peut-être des problèmes lorsqu’on répond à un message signalé par e-mail (ça doit mettre à jour la date de dernière visite).

Je vais donc m’y reporter.

je boucle ce sujet, on le continue ici : https://forum.fiction-interactive.fr/t/bibliotheque-french-h-pistes-damelioration/179/1

En attendant, pensez à mettre à jour la version de vos bibliothèques et veuillez nous rapporter les bugs éventuels rencontrés :
download.tuxfamily.org/informfr/InformLibFR.zip