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

Lisp Discussion :

Seau à vider


Sujet :

Lisp

  1. #1
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut Seau à vider
    Bonjour,

    Je suis bloquée sur un exercice depuis un assez long moment, il faut créer un seau remplie avec (set 'seau '(o o o o)) , et ensuite le vider en utilisant cons et eval (pour évaluer l'expression) :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Break 1 [5]> (cons 'loop (cons 'cond (cons (cons 'not (cons 'seau nil)) (cons '(return seau) (cons 'pop (cons 'seau nil))))))
    (loop cond (not seau) (return seau) pop seau)
    Donc comme l'expression est fausse , lorsque je teste la variable seau , l’interprète me renvoie toujours un seau rempli ...


    En principe , il faut arriver à l'expression suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     (loop (cond ((not seau) (return seau))) (pop seau))
    pour obtenir une bassine vide soit nil .


    J'ai essayé de suivre le raisonnement de l'exemple (+ 10 5) , mais je ne vois pas où se trouvent mes erreurs , à part le manque de quote , et l'utilisation de la fonction eval (au début).


    Je ne demande pas une réponse , mais plutôt une petite piste
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Regardons un sous-problème :
    Si on suit ton code, tu écrirais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (cons 'loop (cons 'cond nil))
    Mais ceci est incorrect et résulte en :
    car :
    correspond simplement à la liste ('cond)
    et :
    consiste en la liste constituée de 'head puis des éléments de tail (où tail est une liste).
    Donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (cons 'loop (cons 'cond nil)) == (cons 'loop ('cond)) == ('loop 'cond)
    Donc si on veut bien :
    il nous faut créer une liste dont ('cond) (la liste contenant 'cond) est un élément, autrement dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (cons 'loop (cons (cons 'cond nil) nil))
    Est-ce compris ? Corrige le reste en suivant ce modèle.

    --
    Jedaï

  3. #3
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    J'ai la solution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (eval (cons 'set
                (cons (cons 'quote (cons 'seau ()))
                      (cons () ())))


    Remarque: j'ai obtenu ce résultat en utilisant la fonction "get-cons":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ELISP> (get-cons '(set 'seau nil))
    (cons 'set
          (cons
           (cons 'quote
    	     (cons 'seau nil))
           (cons nil nil)))
    et on vérifie que c'est bon avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ELISP> (eval (get-cons '(set 'seau nil)))
    (set 'seau nil)
    Sinon on peut aussi utiliser (get-cons '(loop (cond ((not seau) (return seau))) (pop seau))), ainsi qu'en atteste le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ELISP> (set 'seau '(o o o))
    (o o o)
     
    ELISP> (eval (eval (get-cons '(loop (cond ((not seau) (return seau))) (pop seau)))))
    nil
     
    ELISP> seau
    nil
    Juste pour vérifier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ELISP> (eval (get-cons '(loop (cond ((not seau) (return seau))) (pop seau))))
    (loop
     (cond
      ((not seau)
       (return seau)))
     (pop seau))
    Il suffit juste d'écrire "get-cons", mais c'est tellement trivial que c'est laissé en exercice au lecteur... oops! à la lectrice...

  4. #4
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut
    Merci Jedai et jack-ft .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((cond)) == (cons (cons 'cond nil) nil))        # pour obtenir une sous-liste .

    Donc en suivant ce chemin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((not seau)) ==    (cons (cons 'not  (cons 'seau nil)) nil)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (return seau) == (cons '(return seau)
    En imaginant la liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((not seau) (return seau))   == (cons (cons 'not (cons 'seau nil)) (cons '(return seau) nil))
    Mais comment savoir subdiviser les liste qui restent Y'a pas à dire faut avoir l’œil observateur


    Sinon , concernant ta méthode @jack-ft , cette dernière n'est pas encore de mon niveau , l'énoncé est clair : il faut tout considérer comme des atomes , mais je pense que le return est une exception à la règle...
    Cependant , je ne vois pas l'objectif de multiplier l'usage de cons , à part pour rendre complexe la lecture d'un code secret ...
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Kurodiam Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((cond)) == (cons (cons 'cond nil) nil))        # pour obtenir une sous-liste .
    oui

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((not seau)) ==    (cons (cons 'not  (cons 'seau nil)) nil)
    oui

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (return seau) == (cons '(return seau)
    Hummm... on peut appliquer le même principe que pour (not seau) == (cons 'not (cons 'seau nil)):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (return seau) == (cons 'return (cons 'seau nil))


    En imaginant la liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((not seau) (return seau))   == (cons (cons 'not (cons 'seau nil)) (cons '(return seau) nil))
    Attention! pour faire une liste avec A et B, il faut plus que (cons A B). Il faut (cons A (cons B nil))!

    avec A == (not seau) et B == (return seau)

    Mais comment savoir subdiviser les liste qui restent Y'a pas à dire faut avoir l’œil observateur
    C'est pas faux! (et je préfère ma méthode automatique!)

    Sinon , concernant ta méthode @jack-ft , cette dernière n'est pas encore de mon niveau ,
    Cette méthode n'est pas très très compliquée... (juste une petite récursivité de bon aloi) et elle permet juste de tricher, car elle fournit très simplement le résultat que le prof attend!
    Il va de soi qu'on montre au prof le résultat (le paquet de cons) et non la manière dont on l'a obtenu... hé! hé!

    l'énoncé est clair : il faut tout considérer comme des atomes , mais je pense que le return est une exception à la règle...
    non, non! (voir plus haut)

    Cependant , je ne vois pas l'objectif de multiplier l'usage de cons , à part pour rendre complexe la lecture d'un code secret ...
    C'est un objectif purement pédagogique!
    Mais absolument pas du tout pratique!
    C'est pour bien faire prendre conscience que la structure d'une liste avec des sous-listes n'est jamais qu'un gros paquet bien structuré de cons emboités! si je puis m'exprimer ainsi...

    Du bon usage des cons!

    PS: j'enverrai ma méthode après mes vacances (dans une semaine ou deux (si personne ne l'a donnée avant))

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Cette méthode n'est pas très très compliquée... (juste une petite récursivité de bon aloi) et elle permet juste de tricher, car elle fournit très simplement le résultat que le prof attend!
    Il va de soi qu'on montre au prof le résultat (le paquet de cons) et non la manière dont on l'a obtenu... hé! hé!
    Et le jour du partiel, lorsqu'on n'a pas d'ordinateur et une expression à traduire...

    Bien sûr, il est très intéressant d'écrire soit même une telle fonction et faire cette traduction à la main n'est pas passionnant mais il est assez clair que l'objectif est d'intégrer mieux la structure et la syntaxe des listes chainées en Lisp, ce qui visiblement est nécessaire pour Kurodiam.

    --
    Jedaï

  7. #7
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (loop (cond ((not seau) (return seau))) (pop seau))
    j'ai pensé à nommer des blocs (a (b Y W))

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1 (cons 'loop 2(cons 'cond 3(cons 4 (cons 'not (cons 'seau nil) 3 4(cons '(return seau) nil )3 ) 2 1 (cons 'pop 2(cons 'seau nil) 1 ) 0
    Mais mon code est toujours faux ...

    Une parenthèse ouvrante vaut 1 et une fermante vaut -1 . Comment faut t-il compter ? Et surtout , ce nil est un peu énervant à mettre
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  8. #8
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut
    Merci pour votre aide , j'ai fini par saisir mes erreurs (heureusement , que ce genre de méthode n'est pas souvent utilisé )
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Et, à la demande générale, voici le code de ma (fameuse) fonction get-cons:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun get-cons (x)
      (cond
       ((null x) ())
       ((not (consp x)) (list 'quote x))
       (t (list 'cons (get-cons (car x)) (get-cons (cdr x))))))
    Son code est vraiment ultra-simple (il me semble!):
    Si x est nil, on retourne nil.
    Si x n'est pas un cons, on le quote (c-à-d on retourne une liste à 2 éléments, le symbole QUOTE et x).
    Si x est un cons, on retourne une liste contenant 3 éléments, le symbole CONS, le get-cons de (car x), et le get-cons de (cdr x).

    Élémentaire, non?

  10. #10
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut
    Merci mais ton code n'est pas encore à ma portée.
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  11. #11
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Kurodiam Voir le message
    Merci mais ton code n'est pas encore à ma portée .
    Qu'est-ce que tu ne comprends pas dans ce code? (version optimiste)

    ou bien (version pessimiste): que comprends-tu dans ce code?

    Attention: la réponse "tout" est interdite à la première question, mais pas à la seconde...

  12. #12
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Kurodiam Voir le message
    Bonjour,

    En comptant les parenthèses ouvrantes et fermantes , on voit ceci :

    (loop (cond ((not seau) (return seau))) (pop seau))
    1 2 3 4 3 4 321 2 1 0

    donc l'expression ((pop seau)) se trouve au niveau de cond , le deuxième cons ,non ?
    Je préfère compter sur un éditeur qui compte pour moi (et qui compte aussi beaucoup pour moi) plutôt que de compter moi-même!

    En l'occurrence, avec emacs (ou n'importe quel éditeur qui sait indenter du lisp), j'obtiens ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    (loop
     (cond
      ((not seau) (return seau)))
     (pop seau))
    Ainsi, je VOIS que la boucle "loop" contient 2 instructions, le "cond" et le "pop", donc c'est bon!

    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
    (eval
      (cons
        'loop
        (cons
          (cons
            'cond
            (cons
              (cons
                (cons
                  'not
                  (cons 'seau nil) )
              (cons
                (cons
                  'return
                  (cons 'seau nil) )
               nil ) )
            nil ) )
        (cons
          (cons
            'pop
            (cons 'seau nil) )
    	 nil) ) ) )
    Que veut dire le message de l'interprète "you are in the top-level Read-Eval-print loop....Use the usual editing capabilities .(quit) or (exit) leavrs CLISP"" ?
    Je ne connais pas Clisp, mais le message semble tout à fait normal. Il indique que tu es dans une boucle d'interaction avec l'interprète lisp, c'est-à-dire que Clisp te pose la question "que dois-je calculer?", symbolisée par le prompt "? " ou "> " ou autre (suivant le lisp utilisé). Tu lui indiques ce que tu veux qu'il calcule, par exemple (+ 2 3) et alors il lit (READ) ce que tu viens de taper, puis il l'évalue (EVAL), puis il imprime le résultat (PRINT) et il reboucle (LOOP), c'est-à-dire qu'il affiche de nouveau le prompt pour te demander ce qu'il doit calculer ensuite.
    Le message indique également comment quitter le programme: en tapant (quit) ou (exit), tu appelles la fonction qui quitte Clisp (LEAVE CLISP).

    là , je n'obtiens aucune erreur d'indentation mais çà veut dire que lisp n'arrive pas à évaluer bien le code ou quoi ?
    S'il n'arrivait pas à évaluer, il le dirait!

    Que se passe-t-il lorsque tu lui demandes d'évaluer successivement les 4 instructions suivantes:
    Ici, note bien ce que contient la variable seau!

    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
    (eval
      (cons
        'loop
        (cons
          (cons
            'cond
            (cons
              (cons
                (cons
                  'not
                  (cons 'seau nil) )
              (cons
                (cons
                  'return
                  (cons 'seau nil) )
               nil ) )
            nil ) )
        (cons
          (cons
            'pop
            (cons 'seau nil) )
    	 nil) ) ) )
    et enfin:
    Et maintenant, que contient la variable seau?

  13. #13
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut
    Merci pour ton aide !
    En fait , je viens de trouver le même résultat que toi en relisant mon cours , j'ai compris comment compter les espaces adéquats et les arguments de cons et surtout au début , j'ai complétement oublié l'expression classique donc mon indentation était fausse .
    En revanche , notre professeur nous demande d'apprendre à compter nous-même au lieu d'utiliser un éditeur . En faisant cet exercice , je saisis qu'il faut toujours garder en tête l'expression classique et compter les parenthèses ouvrantes/fermantes.

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
           (cons                #  c'est le deuxième argument de cons = 1 et il est aligné avec le cons 2 .
              (cons
                'pop
                (cons 'seau nil) )     # la parenthèse est collée car elle ferme la ligne .
             nil ) ) ) )         # la parenthèse est décollée car elle ferme un niveau .
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  14. #14
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Kurodiam Voir le message
    Merci pour ton aide !
    En fait , je viens de trouver le même résultat que toi en relisant mon cours , j'ai compris comment compter les espaces adéquats et les arguments de cons et surtout au début , j'ai complétement oublié l'expression classique
    Je suis curieux: qu'appelles-tu "expression classique"?

    En revanche , notre professeur nous demande d'apprendre à compter nous-même au lieu d'utiliser un éditeur .
    ça peut toujours servir de savoir compter les parenthèses, mais ça se discute...

    Parmi les milliers (millions?) de lignes de lisp que j'ai écrites, je ne me souviens pas ne pas avoir utilisé un éditeur "intelligent" (sauf peut-être sur des forums (comme celui-ci) avec du code non testé (ce que j'évite la plupart du temps!)).

    Du coup, mon code est TOUJOURS indenté par l'éditeur, ce qui me permet de le lire et de le vérifier facilement et de manière certaine!

    Le seul cas où je pourrais avoir besoin de compter à la main (ou à l'oeil) serait celui ou une ligne contiendrait beaucoup de niveaux, comme justement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (loop (cond ((not seau) (return seau))) (pop seau))
    Dans ce cas, je peux quand même utiliser l'éditeur en plaçant le curseur après une parenthèse fermante pour voir l'ouvrante correspondante en surbrillance. De plus, j'utilise aussi le module eldoc d'emacs qui affiche en bas de la fenêtre les arguments de la fonction courante avec, en gras, le nom de l'argument attendu à la place du curseur.

    Cependant, ce code reste difficile à lire (au moins pour moi!). C'est pourquoi je le découperais et le ferais réindenter par l'éditeur afin d'obtenir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    (loop
     (cond
      ((not seau) (return seau)))
     (pop seau))
    De cette manière, je vois clairement la structure de cette instruction: une "loop" avec un "cond" à une clause et un "pop".


    En faisant cet exercice , je saisis qu'il faut toujours garder en tête l'expression classique et compter les parenthèses ouvrantes/fermantes.

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
           (cons                #  c'est le deuxième argument de cons = 1 et il est aligné avec le cons 2 .
              (cons
                'pop
                (cons 'seau nil) )     # la parenthèse est collée car elle ferme la ligne .
             nil ) ) ) )         # la parenthèse est décollée car elle ferme un niveau .
    Je me souviens avoir utilisé la technique des espaces avant les parenthèses pour distinguer les parenthèses fermantes de la ligne des parenthèses fermantes des lignes précédentes, mais je l'ai rapidement abandonnée car c'est trop de boulot lorsqu'on coupe une ligne qui ne l'était préalablement pas, comme justement la transformation de l'instruction "loop" précédente (qui passe de 1 ligne à 3 ou 4)!

    Sinon, as-tu essayé de lire tranquillement le pseudo-code que j'ai donné précédemment:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Pour obtenir le get-cons d'un x
      Si x est nil, on retourne nil.
      Si x n'est pas un cons, on le quote (c-à-d on retourne une liste à 2 éléments, le symbole QUOTE et x).
      Si x est un cons, on retourne une liste contenant 3 éléments: le symbole CONS, le get-cons de (car x), et le get-cons de (cdr x).

  15. #15
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Je suis curieux: qu'appelles-tu "expression classique"?

    Sinon, as-tu essayé de lire tranquillement le pseudo-code que j'ai donné précédemment:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Pour obtenir le get-cons d'un x
      Si x est nil, on retourne nil.
      Si x n'est pas un cons, on le quote (c-à-d on retourne une liste à 2 éléments, le symbole QUOTE et x).
      Si x est un cons, on retourne une liste contenant 3 éléments: le symbole CONS, le get-cons de (car x), et le get-cons de (cdr x).
    En fait , je veux dire l'expression sans indentation .

    A ma connaissance , la fonction cons peut avoir deux arguments .Toi , tu as crée une fonction avec un clause qui permet de vérifier la nature de x , le symbole signifie en fait ' donc si x n'est pas un cons , la fonction retourne 'x . Ensuite , si x est un cons , la liste retournée doit prendre en compte le symbole cons et les deux arguments de x .
    Cette fonction pourrait me servir à limiter mes erreurs au moment de créer des codes remplis de cons ( çà peut donner le tourni parfois) ...

    Voilà , est-ce mon explication est correcte ?
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  16. #16
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Kurodiam Voir le message
    En fait , je veux dire l'expression sans indentation .
    ok

    A ma connaissance , la fonction cons peut avoir deux arguments .
    Farpaitement! Je dirais même plus: elle DOIT avoir 2 arguments!

    Toi , tu as crée une fonction avec un clause qui permet de vérifier la nature de x ,
    Tout à fait. Et qui fait des traitements différents en fonction de la nature de x.

    le symbole signifie en fait ' donc si x n'est pas un cons , la fonction retourne 'x .
    Quasiment exact! Je dirais même plus que c'est la principale difficulté!
    Je ne dirais pas que la fonction retourne 'x... car l'évaluation de 'x retourne le symbole x et non son contenu!
    Lorsqu'on évalue une liste qui contient le symbole QUOTE et un truc, ça retourne ce truc (sans l'évaluer!). Ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ? (quote (a b c))
    => (a b c)
    En fait, dans ce cas, get-cons construit une liste contenant le symbole QUOTE et la valeur contenue dans la variable x. Par exemple, si la valeur de x est le symbole COUCOU (obtenu avec (set x 'coucou), alors l'évaluation de (list 'quote x) retourne la liste (quote coucou) qui est identique à 'coucou et qui, une fois évaluée, donnera bien le symbole COUCOU qui était contenu dans x... Ouf!

    Ensuite , si x est un cons , la liste retournée doit prendre en compte le symbole cons et les deux arguments de x .
    Si, par "les deux arguments de x", tu veux dire le CAR et le CDR de x, alors oui! Mais on parle d'arguments pour une fonction, et non pas pour un cons. Je ne sais même pas s'il existe un terme générique englobant le CAR et le CDR d'un CONS! Peut-être pourrait-on dire les constituants du CONS? ou les éléments?

    Donc, pour bien préciser, je dirais plutôt que, lorsque x est un cons, il faut retourner une instruction qui, une fois évaluée, crée un cons identique au contenu de x.
    Cette instruction doit donc comporter le symbole 'CONS, suivi de 2 arguments qui permettront de construire respectivement le CAR et le CDR de x.
    Or, c'est justement ce qu'est censée faire la fonction get-cons! Il suffit donc d'appeler get-cons sur le CAR de x, puis sur le CDR de x et d'ajouter ces 2 résultats à la liste qui contient déjà le symbole 'CONS.

    Je ne dis pas que cette fonction est facile à écrire, mais elle me semble facile à lire!

    Cette fonction pourrait me servir à limiter mes erreurs au moment de créer des codes remplis de cons ( çà peut donner le tourni parfois) ...
    C'est pas faux!

  17. #17
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Si, par "les deux arguments de x", tu veux dire le CAR et le CDR de x, alors oui! Mais on parle d'arguments pour une fonction, et non pas pour un cons. Je ne sais même pas s'il existe un terme générique englobant le CAR et le CDR d'un CONS! Peut-être pourrait-on dire les constituants du CONS? ou les éléments?

    Donc, pour bien préciser, je dirais plutôt que, lorsque x est un cons, il faut retourner une instruction qui, une fois évaluée, crée un cons identique au contenu de x.
    Cette instruction doit donc comporter le symbole 'CONS, suivi de 2 arguments qui permettront de construire respectivement le CAR et le CDR de x.
    Or, c'est justement ce qu'est censée faire la fonction get-cons! Il suffit donc d'appeler get-cons sur le CAR de x, puis sur le CDR de x et d'ajouter ces 2 résultats à la liste qui contient déjà le symbole 'CONS.

    Je ne dis pas que cette fonction est facile à écrire, mais elle me semble facile à lire!

    C'est pas faux!
    Merci pour l'explication!
    Oui , je voulais dire par les deux arguments de x CAR et CDR. Ensuite , il suffit d'initialiser à chaque fois la variable x , et en tapant (get-cons x) .
    En tout cas , c'est une fonction très intéressante à utiliser , une fois que l'on saisit bien le pseudo-code mais celle-ci n'est pas évidente à coder sans prendre un peu de recul .

    Dans l'expression ((not (consp x)) , quelle est la signification de consp ? Déjà le not (opérateur booléen et null est l'équivalent) est là pour inverser le sens de la valeur logique .
    Par contre , le t à la fin , est t-il utilisé dans le cas où x serait une liste vide ou bien c'est le fait de remplir une liste vide avec les arguments de x et le symbole CONS ?
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  18. #18
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Kurodiam Voir le message
    Ensuite , il suffit d'initialiser à chaque fois la variable x , et en tapant (get-cons x) .
    On peut aussi directement taper (get-cons '(loop (cond ((not seau) (return seau))) (pop seau))) sans affecter de variable x.

    Dans l'expression ((not (consp x)) , quelle est la signification de consp ?
    cf. http://www.lispworks.com/documentati...onsp.htm#consp dans l'index (cliquer ici).

    Returns true if object is of type cons; otherwise, returns false.
    Les fonctions dont le nom se termine par la lettre "P" sont des prédicats (ils effectuent un test sur leur argument et retournent un booléen).
    La fonction CONSP teste si son argument est un CONS.
    La fonction INTEGERP teste si son argument est un INTEGER.
    etc.

    Déjà le not (opérateur booléen et null est l'équivalent) est là pour inverser le sens de la valeur logique .
    mais oui! Donc (not (consp x)) est vrai lorsque x n'est pas un cons.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun get-cons (x)
      (cond
       ((null x) ())
       ((not (consp x)) (list 'quote x))
       (t (list 'cons (get-cons (car x)) (get-cons (cdr x))))))
    Par contre , le t à la fin , est t-il utilisé dans le cas où x serait une liste vide
    Non! Pour tester si x est une liste vide, on teste si x est NIL avec (null x) (c'est le test de la première clause).

    ou bien c'est le fait de remplir une liste vide avec les arguments de x et le symbole CONS ?
    Euh... Comment dire...? Le COND est une fonction spéciale qui "étudie" chaque clause. Ici, le COND contient 3 clauses:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       ((null x) ())
       ((not (consp x)) (list 'quote x))
       (t (list 'cons (get-cons (car x)) (get-cons (cdr x))))))
    Chaque clause contient un premier élément qui est un test. Ici, les 3 tests sont donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       (null x)
       (not (consp x))
       t
    Le fonction COND évalue chaque test en séquence. Chaque fois qu'un test rend une valeur NIL, la clause est complètement ignorée et le COND passe à la clause suivante.
    Dès que l'évaluation d'un test rend une valeur true (différente de NIL), alors le COND évalue en séquence les différents éléments restants de la clause (ici, pour chaque test, il n'y a qu'un seul élément de clause) et retourne la valeur du dernier élément de la clause et termine complètement l'exploration des clauses. (voir la macro cond (cliquer ici)).

    Ainsi, si le test (null x) est vrai (c'est-à-dire si x est une liste vide, c'est-à-dire égal à NIL), alors le COND évalue et retourne le reste de la clause, c'est-à-dire juste () et arrête l'examen des clauses.
    Si le test (null x) est faux (c'est-à-dire si x est différent de NIL), alors le COND ignore complètement le reste de la clause et passe à la clause suivante:
    si le test de (not (consp x)) est vrai (c'est-à-dire si x n'est pas un CONS), alors le COND évalue et retourne le reste de la clause, c'est-à-dire (list 'quote x) qui retourne une liste avec le symbole QUOTE et la valeur de x, et le COND arrête l'examen des clauses;
    si le test de (not (consp x)) est faux (c'est-à-dire si x est un CONS), alors le COND ignore complètement le reste de la clause et passe à la clause suivante:
    si le test de t est vrai (ce qui est toujours le cas, quel que soit x!), alors le COND évalue et retourne le reste de la clause, c'est-à-dire (list 'cons (get-cons (car x)) (get-cons (cdr x))))) qui retourne une liste avec le symbole CONS et le résultat de get-cons appliqué à (car x) et à (cdr x).

    Pour résumer, le T dans la dernière clause d'un cond est une sorte de OTHERWISE.

  19. #19
    Membre actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Points : 215
    Points
    215
    Par défaut
    Merci pour l'explication détaillée et les liens

    Je vais relire attentivement , mais j'aimerais savoir s'il existe une fonction qui permet de scanner ce que fait chaque ligne de la fonction (un peu comme print).
    J'ai saisit l'essentiel du code mais l'écriture du code n'est pas encore de mon niveau , par exemple , en cours , j'ai pas encore utilisé () à la place du nil (en principe ) .Moi , j'utilise plus le langage python , mais je suis étonnée du fait que l'on puisse appeler le nom de la fonction à l'intérieur afin de récupérer les deux arguments de x (enfin du moins j'imaginais pas lisp comme çà )
    _""""Cats have a big heart ^^ unlike some bad people (whose will never change in their brain) """

  20. #20
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Kurodiam Voir le message
    Merci pour l'explication détaillée et les liens

    Je vais relire attentivement
    Bonne idée! (ainsi que le zoubi!)

    , mais j'aimerais savoir s'il existe une fonction qui permet de scanner ce que fait chaque ligne de la fonction (un peu comme print).
    Je ne comprends pas ce que tu veux dire

    j'ai pas encore utilisé () à la place du nil (en principe ) .
    En lisp, NIL a statut particulier car c'est plein de choses à la fois!
    - la valeur booléenne qui représente le FAUX
    - un symbole dont le nom est constitué des 3 caractères 'N' 'I' 'L' ( (symbolp ()) retourne T)
    - une liste (vide!) ( (listp 'nil) retourne T!)
    - mais pas un cons!
    (Rq: certains lisps distinguent le symbole NIL et la liste vide (), mais pas Common Lisp.)

    Moi , j'utilise plus le langage python , mais je suis étonnée du fait que l'on puisse appeler le nom de la fonction à l'intérieur afin de récupérer les deux arguments de x (enfin du moins j'imaginais pas lisp comme çà )
    C'est ce qu'on appelle la récursivité!
    C'est très utilisé dans plein de langages (ceux qui savent gérer correctement une pile d'appels (dont pas FORTRAN!)) et en particulier dans des langages comme LOGO ou lisp.

    Un des exercices les plus simples de récursivité (simple) consiste à calculer la longueur d'une liste (qui peut lui-même s'inspirer de somme-n (version récursive de la somme des N premiers nombres)):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Pour LONGUEUR de x
      si x ...
    Si ça te tente!

    Un des exemples les plus "effrayants" de récursivité est la fonction de Wilhelm Ackermann:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    (defun A (m n)
      (cond ((= m 0) (+ n 1))
            ((= n 0 ) (A (- m 1) 1))
            (t (A (- m 1) (A m (- n 1))))))

Discussions similaires

  1. [VBA-E] Vider le presse-papier
    Par tinej dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 12/12/2002, 09h33
  2. [Système] Vider le Presse Papier
    Par babe dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 04/09/2002, 17h46
  3. vider un timage
    Par gIch dans le forum Composants VCL
    Réponses: 2
    Dernier message: 23/08/2002, 23h58
  4. Vider le buffer du clavier
    Par flavien tetart dans le forum x86 16-bits
    Réponses: 2
    Dernier message: 12/07/2002, 08h35
  5. Comment vider un dossier ?
    Par Zinoc dans le forum C++Builder
    Réponses: 3
    Dernier message: 25/06/2002, 14h14

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