VDH-Bruno
Membres-
Compteur de contenus
1 146 -
Inscription
-
Dernière visite
-
Jours gagnés
20
Type de contenu
Profils
Forums
Calendrier
Blogs
Tout ce qui a été posté par VDH-Bruno
-
Test téléchargement fichiers ZIP
VDH-Bruno a répondu à un(e) sujet de (gile) dans Echanges de fichiers
Bonsoir (gile), un retour qui devrait t’intéresser.. Système d'exploitation : XP, Version 2002 Service Pack 3 Fournisseur d'accès Internet Free Utilitaire de décompression : pas d’utilitaire de décompression installé sur mon poste perso ... Test_Standard.zip : Non avec le ZIP Windows Test_BZip2.zip : Non avec le ZIP Windows Test_Deflate.zip : Non avec le ZIP Windows Test_Deflate64.zip : Non avec le ZIP Windows Test_LZMA.zip : Non avec le ZIP Windows Test_PPMd.zip : Non avec le ZIP Windows Le teste semble révéler que c’est avec le zip windows que proviennent les problèmes de téléchargement des fichiers ZIP depuis tes 'pages perso. -
Challenge 33 (liste <-> arbre)
VDH-Bruno a répondu à un(e) sujet de (gile) dans Pour aller plus loin en LISP
Merci (gile), Tu peux t’en féliciter, disons que je m’efforce de comprendre (souvent dans la douleur) deux trois petites choses qui me semblent essentiel, et pour ça ta disponibilité sur ce forum est d’un grand secours. Oupss !! Bien vu effectivement c'était ça.. J’ai recommencé mon benchmark, les résultats sont plus en adéquation avec mes espérances. :) Comme quoi dans certains cas même avec des appels récursifs plus profonds, le résultat n’est pas plus lent si les traitements sont plus immédiats.. [Edité le 15/12/2010 par VDH-Bruno] -
Challenge 33 (liste <-> arbre)
VDH-Bruno a répondu à un(e) sujet de (gile) dans Pour aller plus loin en LISP
Bonjour, La fonction inverse basée sur l’algorithme décrit précédemment (le codage fut laborieux..). (defun bv:tree2lst (Ltree / L t2l) (defun t2l (LtP Lt) (cond ((null Lt) (setq L (cdr L)) nil) ((atom Lt) (setq L (cons Lt L)) (if (null (cdr LtP)) (list L))) (T (append (t2l Lt (car Lt)) (t2l nil (cdr Lt)))) ) ) (mapcar 'reverse (t2l nil Ltree)) ) A l’occasion je me pencherai sur les optimisations.. Car cela reste trés lent au regard de la fonction réciproque livré précédemment (plus un problème du à un algorithme un peu trop "naïf", qu'aux imbrications de listes). Edit du 14/06/2011 : Simplifié l’expression (t2l (setq LtP Lt) (car Lt)) en (t2l Lt (car Lt)) [Edité le 14/6/2011 par VDH-Bruno] -
Merci (gile) Cela me semble on ne peut plus clair, je sais maintenant vers ou orienter mes recherches :D . A+ Bruno
-
Challenge 33 (liste <-> arbre)
VDH-Bruno a répondu à un(e) sujet de (gile) dans Pour aller plus loin en LISP
Bonsoir, Je me suis un peu essayé sur ce chalenge, force et de constater que je suis encore un peu tendre pour ce type d’exercice. Faute de pouvoir présenter un code fonctionnel, je peux essayer de vous donné la direction dans laquelle je suis partie. Pour (tree -> lst) Je me suis représenté l’arbre graphiquement (ce qui me laisse croire que nil et la clef) , dans ma tentative de codage je parcours toutes ses extrémités sans problème de façon récursive avec car et cdr. Ce que je n’arrive pas à implémenter dans mes appels récursifs c’est le stockage de la parenté, pour que : Si une feuille est suivi d’un nil --> renvoyer la feuille (atome) et tous ses parents dans une liste. Si un nil est suivi d’un nil --> renvoyer nil. Pour (lst-> tree), J’ai pas encore vraiment commencé à coder Il m’apparait que la clef du problème ce situe sur la répétition des termes, je pense regarder une solution qui mettrais la liste à plat (tous les éléments aux mêmes niveaux), puis avec member (comme fonction de teste de présence d’un élément d’un la liste). Tenter une reconstruction de cette dernière en commençant par la fin. Voilà ce que j’ai de plus simple en tête mais je n’arrive pas à le coder même de façon maladroite, en espérant être meilleur pour de prochains chalenges. -
Merci à tous les deux pour vos réponses, Je dois avouer tout de même que, j’ai un problème de vocabulaire pour bien saisir la portée de vos propos. En ce qui concerne les données étendues ( xdata), j’ai un peu épluché la documentation DXF, la notion ne met pas étrangère, je pense même me faire une bonne idée de la chose.. Par contre les termes registres et dictionnaires me sont encore étrangers, je ne visualise pas ce à quoi vous faite référence, à l’occasion je ferais des recherche en ce sens. (Ps: Il semblerai à vous lire que le registre n'a pas le même sens pour vous, que ce que j'ai nommé la base de registre.dans mon post) A+ Bruno [Edité le 4/12/2010 par VDH-Bruno]
-
Merci Fraid Je regarde de suite
-
Bonjour à tous, J’ai commencé à coder mes premières petites routines (pour le moment j’essaye de faire simple et efficace), à force de patience et de travail, ainsi qu’avec l’aide puisé sur ce forum, je réussi à solutionner la plus part des problèmes rencontrés (pour cela je remercie les membres de ce forum pour l’aide qu’ils m’ont fournis). Pour rendre mes routines un peu plus conviviales, je me suis intéressé à la création de variable d’environnement histoire de mémoriser (sauvegarder) des paramètres de configuration (propre à mes routines ou à mon environnement de travail). En convention je préfixe mes noms de variables avec mes initiales lorsque la variable n’est pas spécifique à une routine sinon je préfixe son nom en fonction de la routine qui va avec. Cas 1 : Dans le cas ou j’ai un seul paramètre d’environnement à définir dans mon code. D’une manière générale comment je procède : Je teste l’existence de ma variable d’environnement (if (getenv "MaVariable") Si elle existe je stocke sa valeur dans un symbole (setq valvar (getenv "MaVariable")) Sinon je la crée en lui affectant une valeur par défaut (au format chaine), éventuellement je récupère sa valeur. (setq val-var (setenv "MaVariable" val-defaut)) ) Dans le déroulement de mon programme, si je viens à modifier la valeur de mon symbole val-var, je mets à jour ma variable. (setenv "MaVariable" val-var) Cas 2 : Dans le cas ou j’ai plusieurs paramètres d’environnement à définir dans mon code. Plutôt que de créer plusieurs variables ( au risque de polluer ma base de registre), j’ai choisi de procéder d’une façon plus « lispienne » c'est-à-dire : Je regroupe tous mes paramètres dans une liste (associative ou pas). (setq lstparm ‘(parm1 parm2 parm3 …)) Puis je converti cette liste en chaîne que je mémorise dans ma variable d’environnement. (setenv "MesVariable" (vl-princ-to-string lstparm)) Si je veux lire la valeur d’un paramètre, par exemple le 2ème (cas ou ma liste n’est pas associative). (setq parm2 (cadr (read (getenv "MesVariable")))) Ou si je veux récupérer ma liste de paramètres (setq lstparm (read (getenv "MesVariable"))) Maintenant que j’ai résumé comment je procède avec setenv & getenv, mon questionnement est le suivant : En 1-La méthode employé vous semble-t-elle acceptable. Dans mon 2ème cas le fait de convertir une liste en chaîne, cela pose t’il un problème de précision dans le cas de nombre réel ( j’ai pas complément fini mes évaluations en ce sens), car dans ce cas je ne fait pas intervenir la fonction rtos. En 2-Qu’elle est la taille maximal des informations que je peux stocker dans ma variable ( surtout pour le cas ou je stocke des listes). En 3- Il me semble avoir compris que les variables définit pas setenv le sont dans la base de registre, mais qu’est ce qu’une base de registre ? Ou est elle localisée ? En 4- Vous vous doutez bien que pour en arriver là, j’ai passablement « pollué » ma base de registre avec la création de variables inutiles au cours de mes diverses tentatives. Pour être le plus propre possible j’ai bien mis mes variables inutiles à "" (c.a.d. nil). Est-ce suffisant car il me semble que cela libère l’espace mémoire mais ne supprime pas le nom du symbole dans la base. Voilà si quelqu’un peux me renseigner (même partiellement), en attendant je continue mes recherches.. A+ Bruno
-
Bonsoir, Ca donne envie mais faut se montrer raisonnable je viens juste de débuter en Lisp, alors dans 2 ou 3 ans peut-être… :D Si je réagi à ton post c’est parce que, j’ai été très agréablement surpris de reconnaitre la syntaxe OCaml que j’ai découvert tout récemment il y a 2 ou 3 semaines. En continuant pour ma culture personnel mes recherches sur la récusions terminal, le Lisp implémenté dans AutoCAD n’étant pas optimisé pour cela. Les meilleures discussions francophones que j’ai trouvées sur ce thème, je les ai trouvés en OCaml (langage apparemment utilisé pour l’enseignement de la programmation en France), j’ai été très surpris avec qu’elle facilité il m’a été possible de les traduire en Lisp. Avec le peu de recul que j’ai, je pense qu’effectivement c’est une bonne nouvelle pour les lispeurs chevronnés vu que d’après le lien F# est dérivé d’ OCaml. (Ps : Pour la vitesse supérieure, j’aimerai bien mais je ne me sens pas encore prêt ;) )
-
Bonsoir, Merci à vous deux, car loin d’avoir pollué le sujet vous l’avez considérablement enrichie et (gile) en plus de ramener la discussion d’une main de maître en plein dans le sujet, à en prime livré une jolie démonstration sur la " primordiale importance de l'algorithmie", Thème sur lequel je n’avais osé m’aventurer, c’est pourquoi en introduction j’avais limité mon sujet : Maintenant que la notion d’algorithme récursif a été abordé, j’essayerai d’enquiller (à l'occasion..) sur ce thème avec les quelques généralités que j’ai pu synthétiser, ainsi qu’une petite réflexion (qui me tient à cœur) sur la récursivité et sa soi-disant lenteur.. Tramber : Je suis heureux que mon post ait pu susciter ton intérêt, hé oui l’absence des SETQ (et donc des variables) c’est tous ce qui fait l’élégance et la concision du codage enveloppé. Sinon enlever l’étaiement à 28 jours ça fait un peu bretelles et ceinture, tu ne trouve pas ? (gile) Merci pour les applaudissements, ça m’encourage car c’est pas toujours évident de se motiver le soir pour bucher après une journée de travail, et même si jusqu’ici " les progrès sont fulgurants" c’est sur des points très très limités et pas encore suffisamment nombreux pour commencer à voir un réel retour sur investissement en terme de routines. [Edité le 19/11/2010 par VDH-Bruno]
-
Carboleum, je vois que la simplification n’a pas échappé à ta sagacité et je t’en remercie :cool: Hé oui je dis une chose et je fais le contraire!!! Je m’en étais rendu compte ce matin au réveil en y repensant, j’ai pas eu le temps de modifié, je corrigerai et re-moulinerai les explications en conséquence ce soir.. ;) Merci (Ps: j'avais tout de même pas poussé la simplification jusqu'au if, il est vrai que dans ce cas cela ne pose pas de problème contrairement à un cond..) EDIT: C'est fait :) [Edité le 17/11/2010 par VDH-Bruno]
-
Bonjour, En tant que débutant, je me lance dans une tentative d’explication sur comment à écrire une fonction récursive d’une façon que j’espère méthodique (c’est celle que je me suis faite), en espérant amener une approche différente de celle déjà proposé dans ce forum, et à l’attention de ceux qui souhaiteraient faire leurs premier pas dans ce domaine. Mon propos porte plus sur la mécanique d’écriture plutôt que sur la détection d’un algorithme récursif (ce qui est à mon sens un autre aspect du problème) (Pour une définition de la récursion et une autre explication voir ce post) A titre d’illustration, j’ai choisi un exemple très simple : Réécrire la fonction lenght Exemple : C’est le type de fonction qui s’écrit très facilement avec while ( de façon itérative), justement je vais m’appuyer dessus pour la méthodologie que je propose d’employer. Avec while comment je procédais: (il y a encore quelques mois de cela :( ) 1 - Je définissais mon nom de fonction et son argument: (defun wh-length (lst) ... ) 2 - Puis ma boucle et la condition de sortie de boucle, ainsi qu’une instruction pour vérifier son bon fonctionnement. ((defun wh-length (lst) (while lst (princ "\n") (princ (setq lst (cdr lst))) ) ) Console Visual LISP 3 - Et enfin j’habillai le tout pour obtenir le résultat escompté (defun wh-length (lst / compt) (setq compt 0) (while lst (setq lst (cdr lst) compt (1+ compt) ) ) ) Console Visual LISP De façon récursive on peut (je pense) adopter le même principe Etape 1 – Définir le nom de fonction et son argument: (defun rc-length (lst) ... ) Etape 2 – Construire l’appel récursif et sa condition d’arrêt, puis tracer ses appels pour vérifier son bon déroulement avant d’écrire la suite. (defun rc-length (lst) (if lst (rc-length (cdr lst)) ) ) (cdr lst) passé en argument réduit la liste d’un élément à chaque appel de rc-length jusqu'à satisfaire la condition d’arrêt (basé sur la validité du symbol lst). (Code très similaire avec celui fait en 2 pour la boucle while) Pour visualiser les appels récursif, il y a la fonction trace bien plus élégante que l’insertion de mes princ de l’exemple précédent. Console Visual LISP Fenêtre de suivie Saisie (RC-LENGTH (1 2 3 4 5)) Saisie (RC-LENGTH (2 3 4 5)) Saisie (RC-LENGTH (3 4 5)) Saisie (RC-LENGTH (4 5)) Saisie (RC-LENGTH (5)) Saisie (RC-LENGTH nil) Résultat: nil Résultat: nil Résultat: nil Résultat: nil Résultat: nil Résultat: nil La fonction s’appelle bien (ou boucle) jusqu’à remplir la condition d’arrêt nil, on peut passer à l’étape numéro 3 car en l’état la fonction ne retourne rien. Etape 3 – Habiller la fonction pour obtenir le résultat voulu. C’est.à.dire. incrémenter un compteur à chaque appel de rc-length pour comptabiliser le nombre l’élément de la liste. Pour cela on va initialiser le compteur à 0 dans la condition d’arrêt, en modifiant légèrement la structure du if (pour mieux visualiser la condition d’arrêt ) (if (null lst) (setq compt 0) Le compteur devenant la valeur de retour pour l’appel le plus imbriqué. On peut maintenant incrémenter chaque appel enveloppant de rc-length avec la syntaxe suivante : (setq compt (1+ (rc-length (cdr lst)))) Note: Dans un premier temps, j’ai volontairement introduit une variable comme on pourrait être tenté de le faire ( par habitude des boucles itératives), et comme il m’arrive encore de le faire (voir réponse de Carboleum) Le code (defun rc-length (lst / compt) (if (null lst) (setq compt 0) (setq compt (1+ (rc-length (cdr lst)))) ) ) Console Visual LISP Fenêtre de suivie Saisie (RC-LENGTH (1 2 3 4 5)) Saisie (RC-LENGTH (2 3 4 5)) Saisie (RC-LENGTH (3 4 5)) Saisie (RC-LENGTH (4 5)) Saisie (RC-LENGTH (5)) Saisie (RC-LENGTH nil) Résultat: 0 Résultat: 1 Résultat: 2 Résultat: 3 Résultat: 4 Résultat: 5 rc-length à maintenant le fonctionnement voulu, mais si on veut pousser l’analyse un peu plus loin il y a encore de petites simplifications possibles. Etape 4 – Optimisation des variables du code. Si on observe le déroulement de la fonction, l’argument lst est utilisé à l’ empilement des appels jusqu’à satisfaire la condition d’arrêt. Alors l’appel le plus imbriqué retourne 0 à la fonction enveloppante (ou appelante) qui s’incrémente de +1 au dépilement des appels. Ce qui pourrait ce traduire par : (1+ (1+ (1+ ( 1+ (1+ 0))))) retourne 5 0 et (1+ (rc-length (cdr lst))) sont les valeurs de retour de la fonction, il est donc inutile de mémoriser leurs valeurs dans une variable comme on le ferait dans une boucle while. Pour if on peut également simplifier, en remplaçant l’expression (null lst) par lst, sans oublier d’inverser l’ordre des deux lignes suivantes. Le code finalisé (defun rc-length (lst) (if lst (1+ (rc-length (cdr lst))) 0 ) ) Effectivement c’est beau.. :D Epilogue Comme il n’y a guère d’intérêt à écrire une fonction qui n’apporte rien de plus que la fonction lenght, nous allons la modifier encore un petit peu, histoire de... ;) (defun rc-length (x) (cond ((and (atom x) (not (null x))) 1) ((null x) 0) (T (1+ (rc-length (cdr x)))) ) ) Résultat A comparer avec En espérant avoir été suffisamment clair pour que cela puisse aider d’autre débutant. (Ps : Toutes précisions et/ou contestations sont les bienvenus cela ne pourra que me faire progresser :D ) Salutations Bruno (Edit message corrigé) [Edité le 17/11/2010 par VDH-Bruno]
-
Bonsoir, Tramber : Tout à fait d’accord avec toi. Et généralement pour en faire 1001, c’est bien souvent au détriment du temps de sommeil, tout en essayant de rester dans la limite du raisonnable.. ;) Bonuscad : Merci de ces précisions, et bien vu l’aparté.. :cool: Ah ces fameuses paires pointées comme je ne travaille pas avec, je n’ai pas toujours le réflexe de les intégrer dans mes raisonnements.
-
Bonsoir, (gile) une fois de plus je te remercie pour tes précisions, concernant les noms de symbole, je suis convaincu de l’utilisation de nom explicite. Pour l’explication complète sur les noms de symbole court donné à l’époque dans l’aide de la R14 : Manuel de personnalisation -> Partie II -- Référence AutoLISP -> Chapitre 15 -- Gestion de la mémoire -> Notes techniques -> Mémorisation des symboles La raison du pourquoi donné à l’époque dans l’aide Manuel de personnalisation -> Partie II -- Référence AutoLISP -> Chapitre 15 -- Gestion de la mémoire -> Espace nodal En recherchant dans l’aide de la 2011 (que je déchiffre très difficilement) ce chapitre semble effectivement avoir disparu depuis.. (Chapitre certainement obsolète depuis) Sinon pour info dans ce fameux chapitre15 il y avait également d’intéressantes explications sur l’emploi de : gc vmon alloc expand et le verrouillage des fonctions nommé en mémoire dans « les tables de page » (en avouant tout de même que beaucoup de ces info me passe encore au dessus de la tête).De toute façon tout ceci ne doit plus être trop d’actualité également.. Pour ce qui concerne la récursion, j’avance bien, l’exercice auquel je me livre sur les concaténations de car et cdr est essentielle dans ma compréhension des listes, j’ai l’impression qu’il m’a ouvert les yeux sur ce qu’est le LISP. Ce sujet Ces listes qui n'en sont pasque j’avais qualifié d’intéressant, me parait maintenant fondamental, je regrette seulement qu’il n’ai pas l’écho qu’il mériterai.. Si tu le permet je pense que j’essaierai un jour de le développer d’avantage.. Pour résumer car et cdr en mode récursif, je dirai que les conditions d’arrêt sont : L’ atome pour car nil pour cdr J’ai découvert tout cela grâce à la représentation des listes en arbre binaire suite à ce fameux post. Arbres binaires dont j’ignorai encore l’existence hier, qui ont l’avantage de mettre en évidence l’implication du nil dans la structure des listes. Salutations Bruno
-
Bonjour, Bon pour ceux qui auraient suivi je m’exerce en ce moment à maîtriser la récursion mutelle. En gros je travaille sur les concaténations de car et cdr pour écrire ma fonction avec en entré la concaténation c" adada"d à réaliser et la liste sur la quelle appliquer la fonction. Fonction qui accessoirement permettrait de dépasser les 4 niveaux de concaténation (dont la limite de concaténation serait dépendent de la pile d’appel,). On peut faire plus simple mais c’est à titre d’entrainement ;) . Au passage ce petit exercice ma fait prendre conscience que les concaténation de car & cdr, c’est comme l’arabe ça ce lit de droite à gauche.. ou alors comme ça s’écrit pour ceux qui ne lisent pas l’arabe (ce qui n’était pas aussi évident au départ dans mon esprit) (cddar ‘((a b c d) (e) f (g f))) retourne (C D) équivalent à (cdr (cdr (car ‘((a b c d) (e) f (g f))))) Ce qui revient à lire a en premier puis d puis d Tout ceci est titre d’introduction car ce n’est pas vraiment mon propos du jour. Mon propos concerne une bizarrerie constaté dans le choix de mon non de fonction, qui m’a amené sur le terrain des choix de nom de fonction pour finir sur une réflexion plus général sur la valeur retourné par l’évaluation d’une fonction. La bizarrerie en question : Je ne livre que les lignes nécessaires à sa compréhension, n’étant pas encore satisfait de mon code : (defun c...r (atm lst / conca ) (setq conca atm) ... ) C _$ (c...r 'ada lst) ADA _$ Analysons un peu _$ C --> # _$ c. --> # _$ c.. --> # _$ c...d --> # _$ c.toto --> # Le fait d’introduire un point dans le non d’une fonction, fait ignorer tout les caractères qui suivent.. (pas la peine d’essayer avec d’autres caractères, j’ai testé pour vous c’est le seul qui à cette propriété) Continuons et généralisons un peu avec les écritures suivantes : _$ car --> # _$ car.o--> # _$ (car.toto '(a b)) A _$ etc.. ect.. Le fait d’introduire un point dans l’appel d’un non de fonction, ne gène en rien son évaluation. (pas la peine d’essayer avec d’autres caractères, j’ai encore testé pour vous c’est toujours le seul qui à cette propriété). Les questions : 1 Le saviez vous ? 2 Pourquoi le point et seulement lui ? 3 Y a-t-il moyen de tirer partie de cette propriété ? Si oui dans qu’elle cas ? (Pour ma part, j’ai pas trouvé) Le choix d’un nom de fonction Voilà tout ceci m’a amené à m’interroger également sur cette question, ce que j’ai réussi à synthétiser : Extrait de l’aide version R14 (je sais ça date un peu) Ce que j’ai testé et qui est accepté malgré la définition de l’aide. _$ (setq A' 1) 1 _$ (setq A. 1) 1 Pour la longueur des noms de fonctions, j’ai supposé qu’il en allait de même que pour les noms de symbole. Sinon pour le reste dite moi si je suis passé à coté de quelques choses.. (histoire que je n’ai plus à me pencher sur cette question du choix des noms de fonctions). Et pour finir, une petite question subsidiaire (la question et pas vital je vous rassure), au cas ou vous connaitriez la réponse: Valeur retourné par l’évaluation d’une fonction. Si j’évalue cdr & ma fonction c...d (renommé depuis) _$ cdr # _$ c...d # Je suppose: SUBR et USUBR représente leur type CDR et C leur nom @0fb0ef78 et @186d4adc certainement une adresse (pointeur) Que représente cette adresse? En quoi peut servir ce type d’information ? Dans quel cas en tirer profit ? Je sais, ça fait beaucoup de questions, j’abuse peut être un peu et si il n’y a pas de réponses, je ne me formaliserai pas, j’ai conscience que ce ne sont que des points singuliers qui ne sont pas bloquant dans mon apprentissage du LISP. Cordialement Bruno (Ps : rectification il n’y a pas que le point qui à ces propriétés l’apostrophe aussi à une ou deux nuance prés) Edit 1 ------------------------------------------------------------------------- Oupss! J’ai peut être posté un peu vite, en relisant après coup le post de (gile) Éléments de syntaxe AutoLISP je m’aperçois que certain thèmes font doublons sur les caractères autorisés, mais d’autres sont complémentaires..) [Edité le 9/11/2010 par VDH-Bruno] [Edité le 9/11/2010 par VDH-Bruno]
-
Merci (gile) pour toutes ces précisions trés intéressantes pour quelqu'un qui comme moi cherche à comprendre, mais dont la culture lui fait cruellement défaut en la matière.. Tes interventions (et liens) en la matière me "prémâche" grandement le travail et je t'en suis trés reconnaissant :D A+ (Ps: en espérant ne pas devenir trop épuisant à la longue avec mes pseudo-réflexions)
-
Bonsoir (gile) A l’occasion de mes différents tests et évaluations.. J’en profite pour apporter ma petite contribution à ton post.. Tests qui ont été motivé par ta remarque dans ce sujet. En cherchant si la limite de calcul avec des réels seraient atteinte avant la limite de la pile d’appel.. Les entiers Codes: ;; Vérif de la limite supérieur des entiers (defun entsup () (setq ent 2147483645) (while (< ent (1+ ent)) (setq ent (1+ ent)) ) ;_ Fin de while ) ;_ Fin de defun ;; Vérif de la limite inférieur des entiers (defun entinf () (setq ent -2147483645) (while (> ent (1- ent)) (setq ent (1- ent)) ) ;_ Fin de while ) ;_ Fin de defun Console VLisp: ENTSUP _$ (entsup) 2147483647 _$ ENTINF _$ (entinf) -2147483648 Sur la vérification de l’intervalle donné pour les entiers, rien à dire c’est les essais auxquelles je me suis livré pour arriver à ces lignes de codes qui sont intéressants Retour d’expérience : 1èrè constatation Je te laisse méditer sur le résultat retourné par ces lignes de codes.. (defun entsup () (setq ent 2147483645) (while ent (setq ent (1+ ent)) ) ) Je pensai naïvement pouvoir m’affranchir du teste (< ent (1+ ent)) dans la boucle while, et profiter d’une erreur (interruption du programme) de l’interpréteur sur la limite des entiers. Puis ensuite interroger la variable définie globalement pour connaître la limite.. Mais que nenni le code à tourné en continue, j’ai du interrompre son exécution, lorsque j’ai interrogé la variable qu’elle fut ma surprise de constater : _$ (entsup) _$ _$ ent -2084132982 _$ Comme si après avoir atteint sa limite haute, elle continuait son incrémentation depuis sa limite basse.. (J’ai recommencé plusieurs fois le teste, résultat toujours aussi surprenant..) 2ème constatation La saisie d’un nombre entier supérieur à sa limite (sup ou inf) le convertie automatiquement en nombre réel _$ (setq int+ 9999999999999999999) 1.0e+019 _$ (setq int- -9999999999999999999) -1.0e+019 Ce qui n’heurte pas spécialement ma compréhension des choses. Contrairement au cas précédent. Les réels De par leur nature il est plus difficile de fixer un intervalle (comme dans le cas des entiers), de ce que j’avais pu en lire: les nombres réels sont calculés avec une précision de 14 chiffres significatifs, Le problème c’est qu’il me semble avoir dépassé cette limite de chiffre significatif dans mes tentatives, je n’ai pas encore trouvé l’algorithme probant qui définirai le nombre de chiffres significatifs d’un nombre réels (ce n’est pas encore ma priorité du moment en matière de Lisp) Voilà si tout cela peut alimenter ce post sur les types de donnée c’est tant mieux.. Amicalement Bruno
-
Récursion enveloppée, finale, croisée..
VDH-Bruno a répondu à un(e) sujet de VDH-Bruno dans Pour aller plus loin en LISP
Merci beaucoup (gile) pour tous ces liens, j’étudie encore la question.. :yltype: Patrick-35, tu as raison avec tout cela je devrai bien arriver à quelque chose, mais pas forcément sur une soirée.. ;) Pour l’instant je découvre, potasse, teste et tente d’analyser.. J’apprends énormément, je note et compare si ça continu, je vais finir par aboutir à une thèse.. :casstet: Bon si je réussie à synthétiser tout cela en quelque chose d’intelligible, je vous en ferai part même si à vos yeux j’enfoncerai certainement des portes ouvertes.. Cordialement, -
Ces listes qui n\'en sont pas
VDH-Bruno a répondu à un(e) sujet de (gile) dans Pour aller plus loin en LISP
Merci, très intéressant ce post :D . -
Récursion enveloppée, finale, croisée..
VDH-Bruno a posté un sujet dans Pour aller plus loin en LISP
Bonjour, En ce moment je me consacrer à la compréhension de ce que l’on nomme la récursivité, étant complètement néophyte en la matière je me suis un peu documenté (source Wikipédia et CADXP ) , En première approche, j’ai testé les codes simples que j’arrivais à comprendre et je me suis amusé à supprimé certaine condition d’arrêt histoire de me confronté avec la notion de pile. Je pense en avoir saisie les grandes lignes que sont : - Le choix des conditions d’arrêts. - L’empilement et le dépilement. - La notion de pile et sa limite (variable suivant ce que l’on empile) - La notion d’ appel enveloppée En second temps, pour continuer sur ma lancé, j’ai essayé de pousser un peu plus loin ( avec bien moins succès je l’avoue..) dans les formes suivantes : La récursion terminale (ou récursion finale) L’intérêt et d’économiser l’espace de la pile. Pour ce faire j’ai-(je pense avoir) adapté l’exemple de la factoriel fourni en sheme, avec l’emploi d’un accumulateur. ;; factorielle récursion terminale: scheme traduit ;; http://fr.wikipedia.org/wiki/R%C3%A9cursion_terminale (defun fact (n) (defun iterer (n acc) (if (<= n 1) acc (iterer (1- n) (* acc n)) ) ;_ Fin de if ) ;_ Fin de defun (iterer n 1) ) ;_ Fin de defun Console visual LISP ------------------- _$ (trace fact iterer) ITERER _$ (fact 5) 120 _$ Fenêtre de suivie ------------------ Saisie (FACT 5) Saisie (ITERER 5 1) Saisie (ITERER 4 5) Saisie (ITERER 3 20) Saisie (ITERER 2 60) Saisie (ITERER 1 120) Résultat: 120 Résultat: 120 Résultat: 120 Résultat: 120 Résultat: 120 Résultat: 120 Le résultat et juste mais visiblement il n’y a pas eu d’économie réalisé sur la pile. Soit l’interpréteur ne sait pas optimiser ce type de récursion, ou plus simplement je n’ai pas réussi à transposer le raisonnement en LISP. Récursion mutelle (ou récursivité croisée) C’est une récursion ou deux (ou plus) fonctions sont définies l’une en termes de l’autre, même si je me fais grosso modo une idée du principe. J’aurais tout de même souhaité savoir si un membre de ce forum aurait un exemple de code (ou lien qui m’aurait échappé) pas trop ardu ( c’est encore tout neuf pour moi) à me fournir. Histoire de regarder comment tout cela s’articule, n’étant pas encore capable dans monter un par moi-même.. Merci, -
Listes arguments de fonctions
VDH-Bruno a répondu à un(e) sujet de VDH-Bruno dans Pour aller plus loin en LISP
Bonsoir, Bon j’ai regardé plus dans le détail vos réponses, c’est impeccable.. à la première comme à la seconde lecture , merci encore (gile) en plus de tes excellentes explications, je suis impressionné par la façon avec laquelle tu as réussi en quelques lignes à expliquer ce à quoi je voulais arriver : Et comment tu as pointé l’approche qui me faisais défaut : Pour conclure ce post et pour ceux qui auraient encore quelques difficultés avec, je vous livre les codes mis en forme ainsi que leurs déroulements sous forme de pas pas. Les codes : ;; centre de gravité (version somme vectorielle) (defun cen-grav (lst) (mapcar '(lambda (x) (/ x (float (length lst)))) (apply 'mapcar (cons '+ lst)) ) ) ;; centre de gravité (transposition d'une matrice) (defun cen-grav (lst) (mapcar '(lambda (l) (/ (apply '+ l) (float (length l)))) (apply 'mapcar (cons 'list lst)) ) ) Pour tester ;; liste de point représentant une forme pyramidale (setq lstpt '((17 0 17) (0 17 17) (17 34 17) (34 17 17) (17 17 34))) (cen-grav lstpt) - Version somme vectorielle – Pas à pas "simplifié" (mapcar '(lambda (x) (/ x (float (length '((17 0 17) (0 17 17) (17 34 17) (34 17 17) (17 17 34)))))) (apply 'mapcar (cons '+ '((17 0 17) (0 17 17) (17 34 17) (34 17 17) (17 17 34)))) ) Etape 1 (mapcar '(lambda (x) (/ x (float 5))) (apply 'mapcar '(+ (17 0 17) (0 17 17) (17 34 17) (34 17 17) (17 17 34))) ) Etape 2: ce qui revient à écrire: (mapcar '(lambda (x) (/ x 5.0)) (list (+ 17 0 17 34 17) (+ 0 17 34 17 17) (+ 17 17 17 17 34)) ) Etape 3 (mapcar '(lambda (x) (/ x 5.0)) '(85 85 102) ) Etape 4: qui peut ce traduire par: (list (/ 85 5.0) (/ 85 5.0) (/ 102 5.0)) Valeur de retour - Transposition d'une matrice - Pas à pas "simplifié" (mapcar '(lambda (l) (/ (apply '+ l) (float (length l)))) (apply 'mapcar (cons 'list '((17 0 17) (0 17 17) (17 34 17) (34 17 17) (17 17 34)))) ) Etape 1 (mapcar '(lambda (l) (/ (apply '+ l) (float (length l)))) (apply 'mapcar '(LIST (17 0 17) (0 17 17) (17 34 17) (34 17 17) (17 17 34))) ) Etape 2 (mapcar '(lambda (l) (/ (apply '+ l) (float (length l)))) '((17 0 17 34 17) (0 17 34 17 17) (17 17 17 17 34)) ) Etape 3: ce qui revient à écrire: (list (/ (apply '+ '(17 0 17 34 17)) (float (length '(17 0 17 34 17)))) (/ (apply '+ '(0 17 34 17 17)) (float (length '(0 17 34 17 17)))) (/ (apply '+ '(17 17 17 17 34)) (float (length '(17 17 17 17 34)))) ) Etape 4 (list (/ 85 (float 5)) (/ 85 (float 5)) (/ 102 (float 5)) ) Valeur de retour -
Listes arguments de fonctions
VDH-Bruno a répondu à un(e) sujet de VDH-Bruno dans Pour aller plus loin en LISP
Bonsoir, Merci à tout les deux pour vos réponses très intéressante, qui devraient occuper mes prochaines soirées :D A la première lecture, je pense en avoir saisi le contenu dans les grandes lignes. Je vais étudier vos réponses plus en détail.. . Je donnerai suite à mon retour (en déplacement pour la semaine). Ps : (gile) j’apprécie grandement le soin et la pédagogie apporté à ta réponse, et effectivement tu peux déplacer le message dans la rubrique "Pour aller plus loin en LISP". -
Bonjour à tous, En continuant ma lecture assidue du forum, j’ai pris la peine de m’attarder 5 mn sur ce post,que je conseil aux autres débutants qui n’auraient pas encore pris soin de le consulter... Après relecture de la consigne je me suis permis cette légère modification (3 => 3.0) (defun cen-grav (p1 p2 p3) (mapcar '(lambda (x1 x2 x3) (/ (+ x1 x2 x3) 3.0)) p1 p2 p3) ) Plus un clin d’œil reconnaissant à l’auteur pour son partage qu’autre chose... que je me permets ici plutôt que sur son post initial, étant donné « ma jeunesse sur le forum » et mon niveau en Lisp. Histoire ne pas rester passif vis-à-vis de mes lectures , j’ai essayé de varianter le code : L’objectif : Généraliser ce code pour n points. (que j’ai à tord cru simple) Pour ce faire j’ai détecté 2 difficultées : 1ere difficulté : Le passage de n arguments (facile) Bon comme la fonction defun ne support qu’un nombre d’arguments prédéfinis, pas de problème je vais lui soumettre les arguments sous forme de liste. (setq lstpt ‘(pt1 pt2 pt3 .. ptn)) 2ème difficulté : Elle découle de la première, soumettre à mapcar non plus une liste de points, mais bien plusieurs listes de coordonnés de points. (Ce qui revient à supprimer un niveau de parenthèse). Hé la je sèche totalement, malgré tout mes tests je n’arrive pas à trouver l’expression qui me permettrais de passer de cette forme : ((x1 y1) (x2 y2) (x3 y3) … (xn yn)) À la suivante pour la soumettre à mapcar: (x1 y1) (x2 y2) (x3 y3) … (xn yn) D’une manière générale : Mais là je conclu peut être hâtivement, j’espère que vous me contredirez, ce que je cherche à obtenir n’est plus vraiment une liste, n’y même une liste de sous listes.. Et donc plus interprétable (n’y réalisable) en AutoLISP. Ce qui revient à dire que l’opération (list '(2 8) '(-4 9) '(20 -2)) qui retourne ((2 8) (-4 9) (20 -2)) Ne serai pas réversible avec une expression du type : (expression ‘((2 8) (-4 9) (20 -2))) qui retournerai (2 8) (-4 9) (20 -2) Ce qui serai je pense une erreur au regard de la syntaxe du LISP. Et donc que mon résonnement de départ conduit à une impasse.. Les questions posées sont les suivantes : Y a-t-il une solution autre que de remanier totalement le code pour surmonter la 2ème difficultés? Ma conclusion est elle juste ? En espérant avoir été suffisamment clair. Cordialement Ps1: Pour un code remanier totalement ce n’est trop pas la peine de plancher à moins que vous ayez un lien tout fait, j’espère avoir les moyens d’y parvenir si il fallait en passer par là. Ps2: Au passage dans mes évaluations de fonctions, j’ai trouvé très intéressant (sur le plan de la réflexion) le comportement de la fonction diviser (/) avec l’introduction d’un réel sur un 3ème terme et non les 2 premiers au regard de la définition donné par l’aide. [Edité le 26/10/2010 par VDH-Bruno]
-
Bonsoir Bred, Ton code m’a beaucoup intéressé, je te propose juste une idée comme ça, histoire d’avoir une autre approche.. en déstructurant les paires pointés ça te conviendrai pas ? Pour déstructurer les paires pointées contenues dans une liste. (setq li (list '(1 "U" 4) '(6 8 "U") '(5 2 8) '(1 . "U"))) ;; Variante n°1 ;; déstructure les paires pointés contenues dans une liste (mapcar '(lambda (x) (if (listp (cdr x)) x (list (car x) (cdr x)) ) ;_ Fin de if ) ;_ Fin de lambda li ) ;_ Fin de mapcar ;; Variante n°2 ;; déstructure les paires pointés contenues dans une liste (mapcar '(lambda (x) (if (atom (cdr x)) (list (car x) (cdr x)) x ) ;_ Fin de if ) ;_ Fin de lambda li ) ;_ Fin de mapcar Retourne En intégrant l’expression à ton code: (defun assoc-full (el lst / ) (vl-remove-if '(lambda (x) (not (member el x))) (mapcar '(lambda (x) (if (listp (cdr x)) x (list (car x) (cdr x)) ) ;_ Fin de if ) ;_ Fin de lambda lst ) ;_ Fin de mapcar ) ;_ Fin de vl-remove-if ) ;_ Fin de defun Teste: (setq e "U") (setq li (list '(1 "U" 4) '(6 8 "U") '(5 2 8) '(1 . "U"))) (assoc-full e li) Retourne: Si le fait de ne pas retrouver ta paire pointé en retour et génant, il est toujours possible d’effectuer l’opération symétrique. (code un peu plus délicat car il crée automatique une paire pointé sur toute les listes paires) (setq li (list '(1 "U" 4) '(6 8 "U") '(5 2 8) '(1 "U"))) ;; Reconstruire les paires pointées (mapcar '(lambda (x) (if (= (length x) 2) (cons (car x) (cadr x)) x ) ;_ Fin de if ) ;_ Fin de lambda li ) ;_ Fin de mapcar Retourne En intégrant de nouveau à ta fonction cela pourrait s’écrire : (defun assoc-full (el lst / ) (mapcar '(lambda (x) (if (= (length x) 2) (cons (car x) (cadr x)) x ) ;_ Fin de if ) ;_ Fin de lambda (vl-remove-if '(lambda (x) (not (member el x))) (mapcar '(lambda (x) (if (listp (cdr x)) x (list (car x) (cdr x)) ) ;_ Fin de if ) ;_ Fin de lambda lst ) ;_ Fin de mapcar ) ;_ Fin de vl-remove-if ) ;_ Fin de mapcar ) ;_ Fin de defun Teste: (setq e "U") (setq li (list '(1 "U" 4) '(6 8 "U") '(5 2 8) '(1 . "U"))) (assoc-full e li) Retourne: J’ai pas testé en profondeur, je l’ai un peu tapé à la volé, si ça te convient je te fait confiance pour trouver d’éventuel optimisation.. Par contre c’est vrai que vu comme cela le code perd un peu de son élégance, mais pour l’instant ça à l’air de fonctionner… Cordialement VDH Edit: Oupss il n'est pas nécessaire de déclarer x comme variable dans assoc-full car c'est l'argument de fonctions lambda et non une variable, je corrige les codes. [Edité le 21/10/2010 par VDH-Bruno]
-
Bonsoir, Patrick_35 : Merci pour l’explication clair du and & or, je n’avais pas encore poussé la comprenette jusque là (tu viens de me faire gagner 2 heures, c’est très appréciable..).Si au fils de mes mails tu en a d’autres comme cela, je suis preneur... . Tramber : Pour faire court et pour finir les présentations J’ai tout d’abord débuté AutoCAD sur la R12 (DOS), même si j’ai croisé de façons anecdotiques les versions 10 et 11. La R14 c’est celle sur laquelle je me suis le plus auto-formé (donc préféré), j’en ai fait le tour le plus complet possible, juste pour le plaisir (avec la doc comme livre de chevet), je me suis initié à la 3D, script, personnalisation : des menus, icônes ect.. (Il restait plus que la programmation), depuis j’avoue me contenté de transposer mes connaissances d’une version à l’autre sans trop m’attarder sur les nouveautés (ça prend déjà beaucoup de temps, une version par an faut pouvoir suivre.. :casstet: ). Professionnellement je sévis actuellement dans une entreprise de préfabrication lourde (béton armé et précontraint), que je résumerai en une petite dizaine d’année en tant que projeteur au sein du BET et plus récemment depuis 3, 4 ans comme technicien d’étude de prix au sein de la cellule commerciale (c’est moins passionnant, mais un peu plus rémunérateur.. :( ). [Edité le 20/10/2010 par VDH-Bruno]
