IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

Erreur de filtrage dans mon match


Sujet :

Caml

  1. #1
    Membre régulier
    Inscrit en
    Septembre 2010
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 78
    Points : 113
    Points
    113
    Par défaut Erreur de filtrage dans mon match
    J'essaye de faire un TP sur les calculs de conditions de vérification. Seulement je bute sur l'une de mes procédures.

    Donc, j'ai 2 fonctions formule2string et expr2string qui prennent respectivement une formule et une expression et qui rend l'expression sous forme de chaine.

    Moi, je dois coder programme2string, qui prend donc un programme et renvoi un string.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    type variable = string
     
    type operateur = Plus | Moins | Mult | Inf | Sup | Infeg | Supeg | Egal
     
    type expression= Const of int | Var of variable 
    		 | BinExpr of operateur * expression * expression
     
    type formule= Expr of expression | Et of formule * formule 
    	      | Ou of formule * formule | Non of formule 
    	      | Implique of formule * formule | True | False 
    	      | Qqsoit of (variable list) * formule
     
     
    type programme= Affectation of variable * expression 
    		| If of formule * programme * programme
    		| While of formule * programme * formule
    		| Bloc of programme list
    		| Skip
     
    type progAnnote= formule * programme * formule
     
    let exempleProg= Bloc([Affectation("x",BinExpr(Plus,Var("x"),Const(1)));
    		       While(Expr(BinExpr(Supeg,Var("x"),Const(0))),
    			     If(Expr(BinExpr(Egal,Var("x"),Const(0))),
    				Affectation("x",BinExpr(Plus,Var("x"),Const(1))),
    				Affectation("x",BinExpr(Moins,Var("x"),Const(2)))),True)]);;
    Voici ma fonction qui pose prob, il s'agit du filtre Bloc, j'ai du mal à le gérer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    let rec programme2string (p: programme) = match p with
        Affectation(v,e) -> (v)^" := "^(expr2string e)
      | If(f,p1,p2) -> "if "^(formule2string f)^" then "^(programme2string p1)^" else "^(programme2string p2)^" endif"
      | While(f1,p,f2) -> "while "^(formule2string f1)^" do "^(formule2string f2)^(programme2string p)^" done"
      | Bloc(b::l) -> "begin "^(programme2string b)^(programme2string (Bloc(l)))^" end"
      | Skip -> " skip ";;
    J'ai également essayé


    Voici ma fonction qui pose prob
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    let rec programme2string (p: programme) = match p with
        Affectation(v,e) -> (v)^" := "^(expr2string e)
      | If(f,p1,p2) -> "if "^(formule2string f)^" then "^(programme2string p1)^" else "^(programme2string p2)^" endif"
      | While(f1,p,f2) -> "while "^(formule2string f1)^" do "^(formule2string f2)^(programme2string p)^" done"
      | Bloc(b::l) -> "begin "^(begin match b with
                 [] -> ""
               |  _ -> (programme2string b)^(programme2string (Bloc(l)) end)^" end"
      | Skip -> " skip ";;
    Bon je suis plus trop sûr du 2eme code. Enfin le 2eme marche, mais mal, en fait je devrais avoir "begin end" qui entoure le bloc, hors là ça entoure chaque élement de la liste de Bloc, pourtant je met "begin end" entre le match.

  2. #2
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonjour,

    En l'état actuel, ce code est laid (je pèse mes mots). Regarde du côté de printf pour éviter de concaténer des dizaines de choses... un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    open Printf
    
    let rec programme2string = function
      | Affectation (v, e) -> sprintf "%s := %s"
        (expr2string e)
      | If (f, p1, p2) -> sprintf "if %s then %s else %s endif" 
        (formule2string f) (programme2string p1) (programme2string p2)
      | While (f1, p, f2) -> sprintf "while %s do %s%s done" 
        (formule2string f1) (formule2string f2) (programme2string p)
      | Bloc (b :: l) -> sprintf "begin %s %s end" 
        (programme2string b) (programme2string (Bloc l))
      | Skip -> " skip "
    Cordialement,
    Cacophrène

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Le problème vient du fait que ton motif (Bloc (b::l)) ne gère pas les listes vides. Comme tu te rappelles récursivement sur (Bloc l) ensuite, la liste perd un élément à chaque sous-appel donc fini par être vide, d'où l'erreur.

    Tu devrais plutôt écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    | Bloc bloc ->
      let print_bloc = ... in
      Printf.sprintf "begin %s end" (print_bloc bloc)

  4. #4
    Membre régulier
    Inscrit en
    Septembre 2010
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 78
    Points : 113
    Points
    113
    Par défaut
    C'est plus élégant c'est clair, cependant dans le TP on travaille avec print_string. Et les autres fonctions déjà faites ( expr2string, formule2string ) sont faites avec print_string.

    M'enfin ce n'est pas sur la forme que j'aimerai avoir de l'aide

  5. #5
    Membre régulier
    Inscrit en
    Septembre 2010
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 78
    Points : 113
    Points
    113
    Par défaut
    Citation Envoyé par bluestorm Voir le message
    Le problème vient du fait que ton motif (Bloc (b::l)) ne gère pas les listes vides. Comme tu te rappelles récursivement sur (Bloc l) ensuite, la liste perd un élément à chaque sous-appel donc fini par être vide, d'où l'erreur.

    Tu devrais plutôt écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    | Bloc bloc ->
      let print_bloc = ... in
      Printf.sprintf "begin %s end" (print_bloc bloc)
    J'avais essayé aussi en rajoutant avec le filtre Bloc un autre filtre comme ça

    Mais ça ne marchait pas, j'avais toujours des "begin...end" en trop.

    Par contre j'ai moins compris ton code

    EDIT: Par contre ma fonction programme2string n'affiche pas la chaine, elle se contente de renvoyer une chaine

    EDIT2: Je remet le code que j'ai et la sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    let rec programme2string (p: programme) =  match p with
        Affectation(v,e) -> (v)^" := "^(expr2string e)
      | If(f,p1,p2) -> " if "^(formule2string f)^" then "^(programme2string p1)^" else "^(programme2string p2)^" endif"
      | While(f1,p,f2) -> " while "^(formule2string f1)^" do "^(programme2string p)^" done"
      | Bloc([]) -> ""
      | Bloc(e::l) ->
        let print_bloc = 
          (programme2string e)^(programme2string (Bloc(l)))
        in
        "begin "^print_bloc^" end"
      | Skip -> " skip ";;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    programme2string exempleProg;;
    - : string =
    "begin x := (x + 1)begin  while (x >= 0) do  if (x = 0) then x := (x + 1) else x := (x - 2) endif done end end"

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Tu as des "begin .. end" en trop parce que tu leur demandes d'être là en faisant un appel récursif sur "Bloc(l)" au lieu d'afficher seulement les instructions de l une par une.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Bloc bloc ->
      let code_bloc = String.concat "; " (List.map programme2string blog) in
      "begin " ^ code_bloc ^ " end"

  7. #7
    Membre régulier
    Inscrit en
    Septembre 2010
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 78
    Points : 113
    Points
    113
    Par défaut
    Merci ça marche impec. C'est dommage d'avoir due utiliser List et String, mais je pense que y avait pas le choix pour faire quelque chose de concis et propre.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Bloc bloc ->
      let rec code = function
        | [] -> ""
        | [prog] -> programme2string prog
        | hd::tl ->  programe2string hd ^ "; " ^ code tl in
      "begin " ^ code bloc  ^ " end"

  9. #9
    Membre régulier
    Inscrit en
    Septembre 2010
    Messages
    78
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 78
    Points : 113
    Points
    113
    Par défaut
    Merci beaucoup bluestorm!

    En passant, c'était très intéressant ton article sur coq. J'étudie ocaml en licence et on a abordé en fin de module la vérification de programme, mais je dois dire que je suis littéralement tombé amoureux d'ocaml, c'est vraiment un chouette langage !

    Voilà c'était ma parenthèse I<3Ocaml

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [phpMyAdmin] Erreur de syntaxe dans mon script de création
    Par piotrr dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 3
    Dernier message: 18/08/2008, 15h45
  2. Erreur Controle.dll dans mon application
    Par saliouseck dans le forum Access
    Réponses: 0
    Dernier message: 11/04/2008, 14h18
  3. [MySQL] Erreur quelque part dans mon compteur de visites !
    Par MathMan dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 26/06/2007, 04h59
  4. Erreur du serveur dans mon application
    Par lion000 dans le forum ASP.NET
    Réponses: 1
    Dernier message: 19/05/2007, 00h06
  5. [XML] Rss, erreur de syntaxe dans mon flux?
    Par Soten dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 30/04/2007, 09h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo