Visual LISP para AutoCAD 2000
Visual LISP para AutoCAD 2000
Visual LISP para AutoCAD 2000
PRIMERA PARTE:
EL ENTORNO DE DESARROLLO VISUAL LISP
SEGUNDA PARTE:
TCNICAS FUNDAMENTALES DE LA PROGRAMACIN
LISP
1. TIPOS DE DATOS
TOMOS
o TOMOS SIMBLICOS (S-ATOMS)
o CONSTANTES
NMEROS
CADENAS DE TEXTO
o LISTAS Y CONSES
LISTAS DE UN NIVEL
LISTAS ANIDADAS
LISTAS DE ASOCIACIN (A-LIST)
LA LISTA VACA (NIL)
o FUNCIN TYPE: EXAMEN DEL TIPO DE DATO
TIPOS DE DATOS LISP
TIPOS DE DATOS AUTOCAD
TIPOS DE DATOS ACTIVE-X
2. FUNCIONES
o FUNCIONES PRIMITIVAS
OPERADORES ARITMTICOS
FUNCIONES DE ACCESO A LISTAS
CONSTRUCCIN DE LISTAS
PROCESAMIENTO DE LISTAS
TRATAMIENTO DE CADENAS
TRATAMIENTO DE CADENAS CON VLISP
o FORMAS ESPECIALES
o FUNCIONES DEFINIDAS POR EL USUARIO
DEFUN: NUEVAS FUNCIONES PARA LA
EXTENSIN DE LISP
REALES A ENTEROS: TRUCAMIENTO
O REDONDEO
FUNCIONES TRIGONOMTRICAS
LAMBDA
FUNCTION
LOAD
o
3. ESTRUCTURAS DE CONTROL
PREDICADOS GENERALES
o PREDICADOS ARITMTICOS
o OPERADORES LGICOS
o OPERADORES LGICOS BINARIOS
Nmeros Binarios
Funcin LSH
Funcin ~ (NOT lgico binario)
Funcin LOGAND
CONVERSIN ENTRE BINARIOS Y
DECIMALES (I)
CONVERSIN ENTRE BINARIOS Y
DECIMALES (II)
Funcin LOGIOR
Funcin BOOLE
o PREDICADOS DEFINIDOS POR EL USUARIO
o ESTRUCTURAS CONDICIONALES
4. FUNCIONES RECURSIVAS E ITERATIVAS
o FUNCIONES RECURSIVAS
EXTRACCIN DE LOS VRTICES DE UNA
POLILNEA
o FUNCIONES ITERATIVAS
REPETICIN UN NMERO DETERMINADO
DE VECES
ITERACIONES SOBRE ELEMENTOS DE
UNA SECUENCIA
CICLOS DEPENDIENTES DE UNA
CONDICIONAL
o FUNCIONES DE MAPEADO SOBRE SECUENCIAS
EXTRACCIN DE LOS VRTICES DE UNA
POLILNEA
Una solucin ms eficaz.
o CUNDO RECURSIN Y CUNDO
ITERACIN?
o
TERCERA PARTE:
ACCESO A LA BASE DE DATOS GEOMTRICA
ANEXO A
ANEXO B
ARCHIVOS LISP Y DCL SUMINISTRADOS CON AUTOCAD:
Versin
Versin
Versin
Versin
Versin
Versin
Versin
2.5
10
11
12
13
14
2000
ANEXO C
EJEMPLO DE MEN PERSONALIZADO (R14):
UTILIDADES VARIAS:
curso
AGRADECIMIENTOS:
INTRODUCCIN:
Xanalys LispWorks
Allegro CL
Corman Common Lisp
CLISP
Visual LISP
La Ventana de la Aplicacin
Barra de Mens
FILE
Creacin de nuevos ficheros de programas abiertos para
su edicin
Apertura de ficheros existentes
Guardar los cambios efectuados
Compilar aplicaciones Visual LISP
Imprimir los ficheros de programas
EDIT
Copiar y Pegar texto
Deshacer el ltimo cambio en el Editor o la ltima
funcin ejecutada desde la Consola
Seleccionar texto en el Editor o la Consola
Comprobar el cierre de parntesis
Recuperar funciones ejecutadas desde la Consola
SEARCH
Buscar y Reemplazar texto
Colocar marcadores de referencia (bookmarks) y
navegar en el texto utilizando estos marcadores.
VIEW
Buscar y mostrar el valor de variables y smbolos en su
cdigo AutoLISP.
PROJECT
Trabaja con los proyectos y la compilacin de programas
DEBUG
Establecer y quitar puntos de ruptura en los programas
Ejecutar programas paso a paso comprobando el estado
de las variables y el valor devuelto por las expresiones.
TOOLS
Establecer las opciones para el formateado del texto y
varias otras opciones del entorno, tales como la
ubicacin de ventanas y barras de herramientas.
WINDOW
Organiza, abre y cierra ventanas en el IDE.
HELP
Pues eso, la Ayuda en lnea.
Cut
Barras de Herramientas
Men Contextual
Teclas Rpidas
Copias de Seguridad
Barras de Herramientas
que encuentre el
trmino buscado, de
manera automtica.
Para ello se deber
marcar la casilla Mark
Instances (Marcar
Buscar y Reemplazar
Instancias)
Permite buscar y reemplazar texto en la ventana activa del Editor. Se
accede a esta opcin desde el men Search>Replace... (Teclas <CTRL>
+ <H>).
Memorizacin de bsquedas anteriores
Los trminos utilizados en bsquedas anteriores se guardan en una lista
desplegable para su reutilizacin.
Insercin de Marcadores
Los marcadores permiten desplazarse dentro del texto de marcador en
marcador. Disponible en el men Search>Bookmarks>Toggle Bookmark.
Hay problemas con los marcadores al usar la opcin de formateo
automtico del texto. (ver nota ms abajo).
Herramientas de Revisin y Formateo
Expresin
Entre las opciones de formateo del texto, adems de la identacin se
incluye la posibilidad de incluir comentarios al cierre de los parntesis
que indican a que funcin corresponden cuando dicha funcin abarca
varias lneas.
Comentado y Descomentado automtico de las lneas seleccionadas
Los comentarios se destacan mediante el esquema de colores elegido
con fondo gris, pero adems de ello, la inclusin de los caracteres <;;;>
al inicio de la lnea se realiza mediante una opcin del men Edit>Extra
Commands>Comment Block y se quitan mediante Edit>Extra
Commands>Uncomment Block.
Si se estuvieran editando archivos DCL, los caracteres introducidos como
seal de comentario sern dos barras inclinadas <//>.
Ayuda
Esta barra de Herramientas incluye tambin el Icono para el Acceso a la
Ayuda en-lnea.
Acceso a Otras Ventanas de la Aplicacin
Autocad
Otras Ventanasde Visual LISP, incluyendo las de otros ficheros abiertos
para su edicin.
La Consola Visual LISP
La ventana de Inspeccin de objetos LISP y AutoCAD.
El Trace Stack, que guarda la memoria de pila de errores.
El Symbol Service para la gestin de Smbolos.
La Utilidad de Apropos.
La Utilidad de Watch.
Utilidades de Depuracin
Symbol Service
Abre el dilogo de la utilidad Symbol Service.
Undo
Deshace la ltima operacin.
Redo
Anula el efecto del ltimo Deshacer (Undo).
Teclas Rpidas
<CTRL> + <S>
Guarda el contenido de la ventana activa del Editor.
<CTRL> + <ALT> + <S>
Guarda el contenido de la ventana activa del Editor con
otro nombre de archivo.
<CTRL> + <SHIFT> + <S>
Guarda el contenido de todas las ventanas de Editor
abiertas.
<CTRL> + <F4>
Cierra la ventana de Editor activa.
<CTRL> + <P>
Imprime el contenido de la ventana de Editor activa.
Comandos de Edicin:
<CTRL> + <Z>
Deshacer la ltima operacin en el Editor. Soporta ilimitadas
Identar
Bloque de
Texto.
Suprimir la
Identacin
de un
bloque de
Texto.
Identar
hasta el
nivel
actual
Aadir un
prefijo a
cada lnea
de texto
selecciona
da.
Aadir
texto al
final de
cada lnea
selecciona
da.
Marcar el
bloque
selecciona
do como
comentari
o.
Desmarcar
como
comentari
o el bloque
selecciona
do.
Guardar
bloque de
texto
selecciona
do a un
archivo.
Convertir
el texto
selecciona
do a
mayscula
s.
Convertir
el texto
selecciona
do a
minsculas
.
Cambiar a
mayscula
s la
primera
letra de
cada
palabra.
Insertar
Fecha.
Insertar
Hora.
Definir el
formato de
fecha y
hora.
Ordenar
alfabtica
mente las
lneas
selecciona
das.
Insertar el
contenido
de un
archivo de
texto en el
lugar
indicado
por el
cursor
Borrar
desde la
posicin
del cursor
hasta el
final de la
lnea.
Borrar
espacios
en torno a
la posicin
actual del
cursor.
Comandos de Bsqueda:
<CTRL> + <F>
Buscar texto.
<CTRL> + <H>
Buscar y sustituir texto.
<CTRL> + <BARRA ESPACIADORA>
Completar una palabra por similitud a otras existentes
en la ventana actual del Editor. Cuando ya se ha
tecleado un nombre anteriormente, El editor VLISP
facilita el incorporarlo de nuevo al documento con slo
teclear los caracteres iniciales. Si en el ejemplo de arriba
quisiramos teclear de nuevo el nombre de la funcin
PosVert bastara teclear Po y despus pulsar <CTRL> +
<BARRA ESPACIADORA>. Si en lugar de encontrar
PosVert encontrara el nombre de variable pos, bastara
con volver a pulsar <CTRL> + <BARRA ESPACIADORA>
cuantas veces fuera necesaro para llegar al texto
deseado.
<CTRL> + <SHIFT> + <BARRA ESPACIADORA>
Completar una palabra mediante APROPOS (buscando
en todo el conjunto de smbolos AutoLISP.
<ALT> + <.>
Poner o quitar marcador.
<CTRL> + <.>
Desplazarse al prximo marcador.
<CTRL> + <,>
Desplazarse al marcador anterior.
<CTRL> + <SHIFT> + <.>
Seleccionar hasta el prximo marcador.
<CTRL> + <W>
Aadir una expresin a la ventana de Vigilancia
(WATCH).
<F9>
Aade o suprime un punto de interrupcin en la posicin
actual del cursor.
<CTRL> + <SHIFT> + <F9>
Suprime todos los puntos de interrupcin.
<CTRL> + <F9>
Busca y resalta el cdigo que dio origen a la ltima
interrupcin.
Herramientas de Desarrollo:
<ALT> + <F6>
Ajusta la ventana activa al espacio disponible en
pantalla.
Comprobacin del cierre de parntesis
Las combinaciones de teclas <CTRL> + <(> y <CTRL>
+ <)> permiten localizar el parntesis de apertura o el
parntesis de cierre respectivamente que corresponda a
partir de la posicin donde se sita el cursor. Si se pulsa
simultneamente <SHIFT> el texto quedar
seleccionado (en vdeo inverso).
Completar Texto
Cuando ya se ha tecleado un nombre anteriormente, El
editor VLISP facilita el incorporarlo de nuevo al
documento con slo teclear los caracteres iniciales. Si en
el ejemplo de arriba quisiramos teclear de nuevo el
nombre de la funcin PosVert bastara teclear Po y
TIPOS DE DATOS
LISTAS
a
juan
45
()
(juan)
(a juan 45 z5mn)
((juan 45) a
((z5mn)))
z5mn
Listas de un nivel
Listas anidadas
La lista vaca
CONJUNTOS DE SELECCIN
Los conjuntos de seleccin son grupos compuestos por
uno o varios objetos (entidades). Las rutinas de
AutoLISP permiten aadir o suprimir de forma
interactiva objetos de los conjuntos de seleccin.
NOMBRES DE ENTIDAD
Un nombre de entidad es un identificador numrico
asignado a los objetos de un dibujo. En realidad, se trata
de un puntero a un archivo mantenido por AutoCAD, en
el que AutoLISP puede encontrar el registro de la base
de datos de objetos. Este puntero suele cambiar de una
sesin de trabajo a otra.
DESCRIPTORES DE ARCHIVO
Los descriptores de archivo son identificadores
alfanumricos asignados a archivos abiertos por Visual
LISP. Cuando sea necesario que una funcin de Visual
LISP lea o escriba en un archivo, debe hacerse
referencia a su identificador.
SUBRUTINAS, SUBRUTINAS EXTERNAS Y
FUNCIONES DE USUARIO
Funciones Nativas LISP o funciones externas cargadas
desde archivos compilados FAS VLX y archivos fuente
LISP.
TABLAS DE PAGINACIN
OBJETOS Y TIPOS DE DATOS ACTIVEX
Objetos propios y determinados formatos para los datos
que se pasan a los mtodos ActiveX.
FUNCIN TYPE
Devuelve el tipo de un elemento designado
(type elemento)
TOMOS
VARIABLES:
Cuando un smbolo se utiliza para almacenar
temporalmente datos necesarios para la ejecucin del
programa suele identificarse como una variable. La
funcin (atoms-family 0) nos devuelve todos los
tomos-S evaluados como no-nil en un momento
determinado.
VARIABLES GLOBALES Y LOCALES:
La funcin SETQ es el medio fundamental para asociar
los smbolos a valores:
(SETQ <smbolo> <valor>)
Esto es equivalente a:
(SET (QUOTE <smbolo>) <valor>)
ENTEROS
Son nmeros sin coma decimal. Los enteros de AutoLISP son
nmeros de 32 bits con signo cuyos valores estn
comprendidos entre +2.147.483.648 y -2.147.483.647.
Aunque AutoLISP utiliza internamente valores de 32 bits, los
que se transmiten de AutoLISP a AutoCAD y viceversa estn
limitados a 16 bits. Por tanto, no pueden transmitirse a
AutoCAD valores superiores a +32767 ni inferiores a -32768.
Sin embargo, VLISP acepta valores fixnum entre los valores
lmite de:
MAX-SHORTINT = 32767
MOST-POSITIVE-FIXNUM = 2147483647
MOST-NEGATIVE-FIXNUM = -2147483647
(fix nmero)
Devuelve la conversin de un nmero real en el prximo
entero menor.
(float nmero)
Devuelve la conversin de un nmero entero en un
nmero real.
LISTAS Y CONSES
LISTAS DE UN NIVEL
Contienen slo tomos.
LISTAS ANIDADAS
Contienen a su vez otras listas que se dicen anidadas.
Estas listas anidadas suelen ser conocidas como sublistas. El nmero de niveles de anidacin no est
restringido ni en su profundidad ni en su complejidad. El
nivel ms externo lo llamamos nivel superior o primer
nivel. A los elementos que conforman este nivel los
llamamos elementos de primer nivel.
LISTAS DE ASOCIACIN (A-LIST)
Son listas anidadas que se utilizan con frecuencia como
estructura de datos en LISP. Una A-LIST es una lista de
pares (CONSES) en que cada par constituye una
asociacin. El CAR de uno de estos pares se conoce
como la CLAVE y el CDR constituye el DATO. Una ventaja
de la representacin como A-LIST es la posibilidad de
incrementarla aadindole nuevas entradas al principio
de la lista. Ms an, como la funcin de bsqueda
ASSOC recorre la A-LIST de manera ordenada, las
nuevas entradas pueden "enmascarar" las ms antiguas
de manera que la informacin puede ser modificada de
forma no destructiva.
LA LISTA VACA (NIL)
Como se dijo antes, es la que no contiene ningn
elemento. Se indica como () y recibe un nombre
particular, el de NIL.
La lista vaca tiene un status peculiar en LISP. Es a la
vez un tomo y una lista. Como smbolo representa el
valor lgico de FALSO:
_$ ()
nil
_$ (atom nil)
T
_$ (listp nil)
T
CIERTO Y FALSO
Su negacin (not nil) sera el smbolo T que representa
la condicin lgica de CIERTO.
El smbolo T es tambin una constante en el sentido de
que slo se representa a s mismo.
En Visual LISP, nil y T as como otros elementos que
incluyen los operadores aritmticos (+, -. etc.) son
smbolos protegidos. Cualquier intento de asignarle otro
(type dato)
La funcin TYPE permite examinar el tipo a que corresponde
un dato determinado. Los datos que evalan como NIL (por
ejemplo tomos simblicos no vinculados a un valor)
devuelven nil.
INT
Nmeros Enteros
REAL
Nmeros de Coma Decimal Flotante
LIST
Listas
STR
Cadenas
SYM
Smbolos
Tipos AutoCAD:
ENAME
Nombres de entidades
FILE
Descriptores de archivo
PAGETB
Tablas de Paginacin de Funciones
PICKSET
Conjuntos de seleccin
SUBR
Funciones AutoLISP internas o funciones cargadas desde
archivos (FAS o VLX) compilados.
USUBR
Funciones de usuario cargadas desde ficheros fuente
LSP.
EXRXSUBR
Aplicaciones ObjectARX Externas.
Tipos ActiveX:
SAFEARRAY
Matriz del tipo Safearray. Las matrices que se pasan a
los mtodos ActiveX deben ser del tipo safearray. Estas
matrices son seguras (safe) porque no es posible el
asignar de manera accidental valores fuera de los lmites
de la matriz provocando una excepcin de datos.
VARIANT
Datos del tipo Variant. Los Variant son en esencia
estructuras que se auto-definen y que pueden contener
diferentes tipos de datos. Por ejemplo, cadenas, enteros
y matrices pueden ser representados por Variants. Junto
a los datos se guarda la informacin que identifica el tipo
de dato. Esta caracterstica de auto-definicin hace de
los Variant tiles medios para pasar parmetros a los
servidores ActiveX.
VLA-object
Objetos ActiveX
FUNCIONES
CAR
CAR admite un nico argumento que debe ser una lista o
una expresin cuyo valor sea una lista y devuelve el
primer elemento de dicha lista. Como LISP siempre
interpreta una lista como una llamada a una funcin,
necesitamos una manera de pasar una lista a CAR sin
que LISP trate de procesarla como llamada a funcin.
QUOTE
Con este objetivo se suministra la funcin QUOTE . Una
lista dentro de una funcin QUOTE no se tratar de
evaluar como llamada a una funcin. La llamada a la
funcin QUOTE se puede abreviar utilizando el signo
apstrofe < >.
CDR
EJEMPLOS:
;Caso de una
La funcin CONS
ASSOC
(assoc elemento lista_asoc)
Busca una lista de asociaciones de un elemento y devuelve la
entrada asociada de la lista
_$ (assoc 10 '((0 . "CIRCLE")(8 . "0")(10 242.426
157.686 0.0)(40 . 27.7503)))
(10 242.426 157.686 0.0)
SUBST
(subst elemento_nuevo elemento_antiguo lista)
Busca un elemento antiguo en una lista y devuelve una copia
de sta con un elemento nuevo en lugar de cada aparicin del
elemento antiguo.
_$ (subst nil "d" '("M" "a" "d" "r" "i" "d"))
("M" "a" nil "r" "i" nil)
_$
STRCAT
(strcat cadena1 [cadena2] ...)
Devuelve una cadena que es la concatenacin de varias
cadenas
_$ (strcat (chr 77) "adrid")
"Madrid"
STRLEN
(strlen [cadena] ...)
Devuelve un nmero entero que indica la cantidad de
caracteres de una cadena
_$ (strlen "Madrid")
6
SUBSTR
(substr cadena inicio [longitud])
Devuelve una subcadena de una cadena
_$ (substr "Madrid" 3 2)
"dr"
STRCASE
(strcase cadena [cul])
Devuelve todos los caracteres alfabticos de una cadena
en maysculas o minsculas
_$ (strcase "Madrid")
"MADRID"
_$ (strcase "Madrid" T)
"madrid"
WCMATCH
(wcmatch cadena patrn)
Realiza bsquedas con patrones de comodines en una
cadena
_$ (wcmatch "Madrid" "?a?r*")
T
_$ (wcmatch "Madrid" "?d?r*")
nil
READ
(read [cadena])
Devuelve el primer tomo o la primera lista contenida en
una cadena
_$ (read "Madrid es una ciudad")
MADRID
_$ (read (strcat "(" "Madrid es una ciudad" ")"))
(MADRID ES UNA CIUDAD)
(vl-prin1-to-string object)
Devuelve la representacin como cadena de cualquier
objeto LISP tal como si fuera la salida de la funcin
PRIN1
_$ (setq file_id (open "test.tmp" "w"))
#<file "test.tmp">
_$ (vl-prin1-to-string file_id)
"#<file \"test.tmp\">"
(vl-princ-to-string object)
Devuelve la representacin como cadena de cualquier
objeto LISP tal como si fuera la salida de la funcin
PRINC
_$ (setq file_id (open "test.tmp" "w"))
#<file "test.tmp">
_$ (vl-princ-to-string file_id)
"#<file test.tmp>"
(vl-string->list string)
Convierte una cadena en una lista de cdigos de
carcter numricos ASCII
_$ (vl-string->list "Madrid")
(77 97 100 114 105 100)
(vl-string-elt string position)
Devuelve la representacin ASCII del carcter situado en
la posicin especificada en una cadena. El primer
carcter ocupa la posicin cero
_$ (vl-string-elt "Madrid" 0)
77
_$ (chr 77)
"M"
_$
(vl-string-left-trim character-set string)
Quita los caracteres especificados del inicio de una
cadena
_$ (vl-string-left-trim "PRE" "PREFIJO")
"FIJO"
FORMAS ESPECIALES
DEFUN
DEFUN-Q
FOREACH
FUNCTION
IF
LAMBDA
REPEAT
SETQ
TRACE
UNTRACE
VLAX-FOR
WHILE
LA PRIMITIVA DEFUN
_$ (doble 1)
2
Un programa Lisp usualmente incluye una coleccin de tales
defuns, asemejndose en ello a un fichero de definiciones de
procedimientos en lenguajes tales como C o Pascal.
Pero, segn puntualiza Graham, "algo muy diferente est
sucediendo aqu. Las funciones Lisp son objetos por s
mismas. Lo que realmente hace DEFUN es construir una
funcin y guardarla bajo el nombre que aparece como primer
argumento."
Podemos acceder a la funcin asociada al smbolo DOBLE
utilizando la funcin Visual LISP vl-symbol-value:
_$ (vl-symbol-value 'DOBLE)
#<USUBR @045677ac DOBLE>
En versiones anteriores de AutoLISP la funcin creada con
defun era una lista:
Command: (defun doble (x) (* x 2))
DOBLE
Command: !doble
((X) (* X 2))
Command: (car doble)
(X)
Command: (cdr doble)
((* X 2))
En Visual LISP la funcin de usuario creada con defun es una
funcin compilada que contiene instrucciones en lenguaje de
mquina, por lo tanto en Autocad 2000 obtendremos:
Command: (defun doble (x) (* x 2))
DOBLE
Command: !doble
#<SUBR @01d5ba28 DOBLE>
Command: (car doble)
; error: bad argument type: consp #<SUBR @01d5ba28
DOBLE>
Command: (cdr doble)
; error: bad argument type: consp #<SUBR @01d5ba28
DOBLE>
EXPRESIONES LAMBDA
.vlx
.fas
.lsp
SIN
(sin ang)
Devuelve el seno de un ngulo expresado en radianes.
COS
(cos ang)
Devuelve el coseno de un ngulo expresado en radianes.
ATAN
(atan num1 [num2])
Devuelve el arcotangente de num1, en radianes, si se le
suministra solamente num1. Si se suministraran ambos
argumentos num1 y num2, ATAN devuelve el arcotangente
de num1/num2, en radianes. Si num2 fuera cero,
devolver un ngulo de ms o menos 1.570796 radianes
(defun infinito ( )
(setq *INF* 2.0)
(while (not (VL-INFP *INF*))
(setq *MAX-REAL* *INF* *INF* (expt *INF* 2))))
_$ (infinito)
1.#INF
_$ *MAX-REAL*
1.34078e+154
_$ *inf*
1.#INF
as tendremos que cualquier nmero dividido entre *INF*
devolver cero y tendremos definida una variable global
*MAX-REAL* que nos permitir comprobar si un valor se
aproxima al mximo valor real admitido por el sistema:
(/ 254.98 *INF*) 0.0
TAN
acepta cualquier ngulo en radianes y devuelve la
tangente en un rango de -9.7E307+epsilon a 9.7E307,
ambos inclusive. Se analiza la posibilidad de que el
coseno del valor pasado sea igual a cero, para evitar un
error de divisin por cero.
(defun tan (z / cosz)
(if (zerop (setq cosz (cos z)))
*INF*
(/ (sin z) cosz)
) ;_fin de if
) ;_fin de defun
SEC
EXPRESIONES LAMBDA
FUNCTION
LOAD
.vlx
.fas
.lsp
ESTRUCTURAS DE CONTROL
PREDICADOS GENERALES:
TOMOS O LISTAS
o TOMOS SIMBLICOS
o TOMOS NUMRICOS
LISTAS VACAS O CONSES
IGUALDAD O IDENTIDAD
TOMOS O LISTAS:
ATOM
Sabemos que dentro de las expresiones LISP se
distinguen los tomos y las listas. El predicado ATOM
verifica si un elemento determinado es un tomo
(atom elemento)
Devuelve nil si elemento es una lista y devuelve T en
caso contrario. Debe tenerse cuidado, si se trata de un
tomo simblico, en tener claro si lo que se quiere
evaluar es el sbolo o su contenido. Si no est precedido
de QUOTE <'>, lo que se evala es el valor asociado:
_$ (atom
T
_$ (atom
T
_$ (setq
(A B C)
_$ (atom
nil
_$ (atom
T
a)
'a)
a '(a b c))
a)
'a)
LISTP
Comprueba si un elemento es una lista
(listp elemento)
Devuelve T si elemento es una lista y devuelve nil en
caso contrario. Obsrvese que como NIL es una lista
vaca, (listp nil) devolver T. Es decir, que todo
tomo simblico no asociado a un valor, devover T
tanto para ATOM como para LISTP:
_$ !b
nil
_$ (atom b)
T
_$ (listp b)
T
_$ (listp 'b)
nil
TOMOS SIMBLICOS:
VL-SYMBOLP
Identifica si un objeto especificado es o no un smbolo.
(vl-symbolp objeto)
Devuelve T si el objeto es un smbolo y nil si se trata de
una constante (nmero o cadena) o una lista.
Este predicado ha sido incorporado por Visual LISP
_$ (vl-symbolp 'a)
T
_$ (vl-symbolp 15)
nil
_$ (vl-symbolp "abc")
nil
_$ (vl-symbolp '(a b c))
nil
BOUNDP
Cuando se trata de un tomo simblico, puede ser
necesario determinar si tiene asociado un valor. BOUNDP
verifica la existencia de dicha asociacin.
(boundp sm)
Devuelve T si sm tiene un valor asociado. Si no hay
ningn valor asociado a sm (o se ha asociado a nil),
boundp devuelve nil. Si sm es un smbolo no definido,
se crea y se asocia a nil de forma automtica.
NUMRICOS:
NUMBERP
Los tomos no simblicos o constantes pueden ser
nmeros o cadenas. NUMBERP comprueba si el objeto es
un nmero (real o entero)
(numberp elemento)
Devuelve T si elemento es un valor numrico y devuelve
nil en caso contrario. El predicado complementario
STRINGP, que comprobara si se trata de una cadena no
est definido en Visual LISP, aunque se puede encontrar
entre los mensajes de error a la hora de depurar un
programa. En el ejemplo que sigue el mensaje "STRINGP
MEMBER
Es un tipo particular de predicado, que comprueba si un
tomo pertenece a una lista dada.
(member expr lista)
Si expr no aparece en la lista, member devuelve NIL. En
caso de encontrarlo, devuelve el resto de la lista, desde
PREDICADOS ARITMTICOS
OPERADORES LGICOS
NOT
Negacin lgica. Cualquier expresin cuyo valor no sea
NIL evala como falsa. En cambio, (not NIL) evala
como T. Esto sucede puesto que cualquier cosa que no
tenga el valor NIL (o la lista vaca) evala en LISP como
T (cierto).
OR
~ (NOT binario)
LOGAND (AND lgico binario)
LOGIOR (OR lgico binario)
BOOLE (operador lgico binario de carcter
general)
SISTEMA BINARIO
6 5 4
0 0 1
64 32 16
0 0 16
4 + 2=22
3
0
8
0
2
1
4
4
1
1
2
2
0
0
1
0
POSICIN
VALOR
BIT DECIMAL
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
11
16
12
32
13
64
14
100
15
256
VALOR
BINARIO
1
10
11
100
101
110
111
1000
1001
1010
10000
100000
1000000
1100100
100000000
16
17
18
512 1000000000
1000 1111110100
1024 10000000000
Funcin LSH
(~ 9) devolvera -10
Lo que sera igual en nmeros binarios con tamao de palabra
de 32 bits a:
1111 1111 1111 1111 1111 1111 0110
El valor negativo se explica, segn lo dicho al explicar la
funcin LSH, al ocupar la posicin extrema izquierda un valor
1. La posibilidad de construir este "filtro negativo" de un valor
binario es extremadamente valioso para gestionar los valores
guardados en trminos de posiciones de bits.
Pero para la gestin de estos valores binarios nos deberemos
auxiliar de otras funciones como LOGAND, LOGIOR, y
BOOLE
No es muy frecuente el uso de esta funcin en los programas
LISP dentro de AutoCAD. Revisando los programas
suministrados con la aplicacin podemos encontrar ejemplos
de su uso en AI_UTILS.LSP y DDMODIFY.LSP de las
versiones 13 y 14 y FORMAT.LSP de la versin 12.
LOGAND
00001101
00010110
00000100
CONVERSIN DECIMAL->BINARIO
cercano.
Se definen las funciones utilitarias BIT y POSBIT, esta ltima
utilizada para guardar el valor de la posicin del bit que se
analiza. La conversin en s misma la realiza la funcin
ConvierteBinario que recibe como argumentos el nmero a
convertir y una funcin predicado a plicar segn el nmero
sea positivo o negativo.
Esta funcin de conversin es llamada desde la funcin
principal BINARIO que analiza si el nmero recibido es
positivo o negativo. En caso de ser negativo pasa a la funcin
de conversin su NOT lgico (~ numdec) y el predicado '= en
lugar del nmero recibido y el predicado '/= que pasara en
caso de ser el nmero positivo.
;;;Binario.lsp
;;;El ciclo continuar hasta que LSH devuelva un
valor negativo
;;;significando que se ha llegado al final de la
palabra (posicin
;;;extrema izquierda). El valor binario es devuelto
en formato de lista.
;;;
;;; Funcin auxiliar Bit: devuelve el valor decimal
del bit en la posicin indicada.
;;;
(defun Bit (pos) (lsh 1 (1- pos)))
;;;
;;;
;;Funcin utilizada como acumulador del valor de la
posicin
;;;
(defun PosBit ()
(if (null posicion)
(setq posicion 1)
(setq posicion (1+ posicion))
) ;_ fin de if
) ;_ fin de defun
;;;
;;;
;;;Funcin para procesamiento del nmero decimal
;;;Recibe como argumento el predicado a aplicar
;;;segn sea el argumento numrico positivo o
negativo
;;;
CONVERSIN BINARIO->DECIMAL
;;;
;;;
;;;Funcin utilizada como acumulador del valor de la
posicin:
;;;
(defun PosBit ()
(if (null posicion)
(setq posicion 1)
(setq posicion (1+ posicion))
) ;_ fin de if
) ;_ fin de defun
;;;
;;;PREDICADOS DEFINIDOS PARA ESTA FUNCIN:
;;;Como filtro de entrada se emplean tres predicados
;;;definidos expresamente para ella:
;;;STRINGP, STD-DOTTED-PAIR-P y BINARIOP
;;;
;;;Predicado STRINGP
;;;Comprueba si el dato es una cadena
;;;(ver PREDICADOS DEFINIDOS POR EL USUARIO)
;;;
(defun stringp (dato) (equal (type dato) 'STR))
;;;
;;;Predicado STD-DOTTED-PAIR-P
;;;Comprueba de que se trate de un par punteado:
;;;Adaptado de la Standard Lisp Library
;;;de Reini Urban:
;;;
(defun STD-DOTTED-PAIR-P (lst)
(and (vl-consp lst) (not (listp (cdr lst))))
) ;_ fin de defun
;;;
;;;Predicado Binariop
;;;Comprueba que la lista incluya valores slo 0 1
;;;
(defun Binariop (numbin /)
(apply 'and
(mapcar '(lambda (term) (or (equal term 0)
(equal term 1)))
numbin
) ;_ fin de mapcar
) ;_ fin de apply
) ;_ fin de defun
;;;
;;;Funcin utilitaria NUMLISTA
;;;
(defun ConvierteDecimal
(numbin / posicion)
(if (Binariop numbin)
(apply
'+
;
suma los valores
de la lista devuelta por MAPCAR
(mapcar
(function
(lambda (x)
(PosBit)
;5.- valora la
variable posicion
(if
(not (zerop x))
(bit posicion)
0
;
en caso
contrario devuelve cero
) ;_ fin de if
) ;_ fin de lambda
7.- y los
valores devueltos quedan en una lista
) ;_ fin de function
(reverse numbin)
) ;_ fin de mapcar
) ;_ fin de apply
nil
) ;_ fin de if
) ;_ fin de defun
;;;
;;;Funcin filtro de entrada, considerando los
posibles tipos de entrada:
;;;Lista, cadena o nmero
;;;los nicos trminos aceptados sern en cualquier
caso ceros o unos
;;;de detectarse otro valor, la funcin devuelve NIL
;;;Otro error derivara de que la lista fuera un par
punteado
;;;Para comprobarlo utilizaramos la funcin STDDOTTED-PAIR-P adaptada de
;;;la Standard LISP library de Reini Urban
;;;
(defun Decimal (numbin /)
(cond
((STD-DOTTED-PAIR-P numbin)
(terpri)
(princ numbin)
(princ " no es un valor admitido.")
(princ)
)
((listp numbin)
;;si es lista, convierte los trminos
(setq
numbin ;;que sean cadenas en nmeros (o
tomos simblicos si fueran letras)
(mapcar
(function (lambda (term)
(if
(stringp term)
(read term)
term
) ;_ fin de if
) ;_ fin de lambda
) ;_ fin de function
numbin
) ;_ fin de mapcar
) ;_ fin de setq
(ConvierteDecimal numbin)
)
((numberp numbin)
;;si es nmero lo convierte en cadena para
despus hacerlo lista
(setq numbin (Numero->Lista numbin))
(ConvierteDecimal numbin)
)
((stringp numbin)
(setq numbin (mapcar 'read (Cadena->Lista
numbin)))
(ConvierteDecimal numbin)
)
(t
(terpri)
(princ numbin)
(princ " no es un valor admitido.")
(princ)
)
) ;_ fin de cond
) ;_ fin de defun
A continuacin algunos ejemplos tomados de la consola de
VISUAL Lisp:
BOOLE
_$
(boole 1
1 1)
1
_$
(boole 2
1 0)
1
_$
(boole 4
0 1)
1
_$
(boole 8
0 0)
-1
Operacin
Booleana
AND
6 (4 + 2)
XOR
7 (4 + 2 +
1)
OR
NOR
Ambos son 1
Slo uno de ellos es
igual a 1
Cualquiera de ellos es
1
Ambos son 0
(complemento de 1)
INTEGERP
Comprueba si el argumento es un nmero entero.
(defun integerp (dato)(eq (type dato) 'INT))
REALP
Comprueba si el argumento es un nmero real.
(defun realp (dato)(eq (type dato) 'REAL))
STRINGP
Comprueba si el argumento es una cadena.
(defun stringp (dato)(eq (type dato) 'STR))
Tipos de Datos AutoCAD:
ENAMEP
Comprueba si el argumento es un nombre de entidad.
(defun enamep (dato)(eq (type dato) 'ENAME))
FILEP
Comprueba si el argumento es un identificador de archivo.
(defun filep (dato)(eq (type dato) 'FILE))
PAGETBP
Comprueba si el argumento es una Tablas de Paginacin de
Funciones.
(defun pagetbp (dato)(eq (type dato) 'PAGETB))
PICKSETP
Comprueba si el argumento es un Conjunto de Seleccin.
(defun picksetp (dato)(eq (type dato) 'PICKSET))
SUBRP
Comprueba si el argumento es una Funcin AutoLISP interna
o compilada.
(defun subrp (dato)(eq (type dato) 'SUBR))
USUBRP
Comprueba si el argumento es una funcin de usuario
cargada desde un fichero fuente LSP.
(defun usubrp (dato)(eq (type dato) 'USUBR))
EXRXSUBRP
Comprueba si el argumento es una Aplicacin ObjectARX
Externa.
(defun exrxsubrp (dato)(eq (type dato) 'EXRXSUBR))
Tipos de Datos ActiveX
SAFEARRAYP
Comprueba si el argumento es una Matriz del tipo Safearray.
(defun safearrayp (dato)(eq (type dato) 'SAFEARRAY))
VARIANTP
Comprueba si el argumento es del tipo Variant.
(defun variantp (dato)(eq (type dato) 'VARIANT))
VLA-OBJECT-P
Comprueba si el argumento es un Objeto ActiveX.
(defun vla-object-p (dato)(eq (type dato) 'VLAobject))
ESTRUCTURAS CONDICIONALES
CONDICIONAL IF
ESTRUCTURA IF-THEN-ELSE
Evala expresiones condicionalmente:
FUNCIONES RECURSIVAS
Los datos que sirven para definir cada una de los objetos
grficos de AutoCAD estn organizados en forma de una lista
de asociacin, es decir, una lista de listas, donde la
informacin guardada en cada sublista se identifica mediante
un cdigo numrico (entero) que aparece como el primer
trmino (CAR) cada sublista. El significado de cada cdigo
coincide en trminos generales con los cdigos que identifican
los datos contenidos en los archivos del formato de fichero
DXF utilizado para la transferencia de dibujos AutoCAD a
otras aplicaciones. Para el desarrollo de la siguiente funcin
basta saber que los valores que corresponden a las
coordenadas X e Y de cada vrtice aparecen en sucesivas
sublistas identificadas mediante el cdigo de asociacin 10. La
coordenada Z aparece en una nica sublista (ya que debe ser
la misma para todos los vrtices) identificada mediante el
cdigo 38. La funcin recursiva descrita a continuacin ser
llamada desde otra funcin que permita seleccionar un objeto
del dibujo, compruebe a continuacin que se trata de la
entidad deseada (del tipo "LWPOLYLINE"), extraiga del objeto
grfico seleccionado la correspondiente lista de asociacin y la
pase, junto con el valor de la elevacin, como argumentos a
la funcin recursiva de extraccin VertPoly.
Funcin ExtraeVertices:
(cons
;la
funcin append permite incluir la
(append (cdr (car lista))(list
elevacion)) ;coordenada Z en la posicin correcta
(VertPoly (cdr lista) elevacion)
;y
contina la recursin
)
)
(t (VertPoly (cdr lista) elevacion))
;si no
es un vrtice
) ;_ fin de cond
) ;_ fin de defun
(defun ExtraeVertices ( / lista_entidad)
(if
(equal
(cdr (assoc 0 (setq lista_entidad (entget (car
(entsel))))))
"LWPOLYLINE"
)
(VertPoly lista_entidad (cdr (assoc 38
lista_entidad)))
(alert "La entidad seleccionada no es una
LWPOLYLINE")
) ;_ fin de if
) ;_ fin de defun
Sin duda este cdigo cumplir su cometido, pero puede ser
mejorado. Este programa est redactado de manera tal que
ninguna de sus partes pudiera reutilizarse en otros futuros
programas. Un enfoque ms eficaz consistira en analizar qu
procesos de carcter ms general intervienen en la solucin y
programarlos como funciones utilitarias que se incorporen
como nuevas herramientas al lenguaje. Ms adelante, y
despus de estudiar algunos otros procedimientos y tcnicas,
intentaremos precisamente esto, cmo abordar de una
manera ms eficaz la solucin a este programa.
FUNCIONES ITERATIVAS
ITERACIONES SIMPLES
REPEAT
Evala cada expresin el nmero de veces que se
especifique en el argumento entero, y devuelve el valor
de la ltima expresin
(repeat entero expresin ...)
El argumento entero debe ser un nmero entero
positivo.
Ejemplos de iteraciones con REPEAT:
FACTORIAL ITERATIVO
Como primer ejemplo analizaremos la funcin FACT2
propuesta por Dennis Shinn <jeeper@halcyon.com>
en el newsgroup comp.cad.autocaden septiembre de
1996. La explicacin es nuestra traduccin libre del
original.
(defun fact2 (n / x y)
(setq x 1 y 1)
(repeat (1- n)
(setq
x (1+ x) y (* x y) )
)
)
En la primera lnea se asigna el valor inicial correcto a
las dos variable que llamamos x e y.
La repeticin se establece para un nmero especfico de
veces segn el nmero que se pase como argumento a
la funcin. Puesto que la operacin del clculo del
factorial implica la cantidad de nmeros a multiplicar
menos 1, establecemos en (1- n) el nmero de
repeticiones.
Ahora vienen los clculos matemticos: (setq x (1+ x)
y (* x y))
Durante cada iteracin de esta expresin, la x se
incrementa por un valor de 1 cada vez, e y se
incrementa como el producto de ella misma y el prximo
valor mayor de x, etc., etc.
Obsrvese que no se ha implementado un control de
errores, que es algo deseable en un lenguaje de
programacin. Tanto 0 como 1 quedan indefinidos, ya
que ninguno de los dos permitir que ocurra la iteracin.
El REPEAT simplemente no repite. Vale, sin embargo
para demostrar las posibilidades de un verdadero
lenguaje de programacin (como LISP) para realizar
verdaderas operaciones de recursin e iteracin.
Como muestra de una implementacin para atrapar
posibles errores podramos crear otra rutina fact3 que
llame a la rutina fact2 slo en los casos apropiados:
(defun fact3 (n)
(cond
((and (numberp n)(> n 1))
(fact2 n)
)
((= n 1) 1)
(t nil)
)
)
FOREACH
Evala cada expresin para todos los miembros de una
lista
(foreach nombre lista expresin ...)
Recorre la lista, asignando sucesivamente cada elemento
de la lista a la variable nombre y evaluando de esta
manera cada expresin para cada uno de los elementos
de la lista representados por nombre. Puede especificar
tantas expresiones como desee. La funcin FOREACH
devuelve el resultado de la ltima expresin evaluada.
VLAX-FOR
Efecta una iteracin a travs de una coleccin de
objetos evaluando cada expresin
(vlax-for smbolo coleccin [expresin1
[expresin2 ...]])
El argumento smbolo ser asignado a cada Objeto-VLA
de la coleccin. El argumento coleccin representa un
objeto ActiveX del tipo coleccin. [expresin1
[expresin2 ...]] son las expresiones a evaluar. La
funcin devuelve el valor de la ltima expresin
evaluada para el ltimo objeto de la coleccin.
Ejemplos de iteraciones con FOREACH:
(42 . 0.0)
(10 202.747 163.648)
(40 . 0.0)
(41 . 0.0)
(42 . 0.0)
(10 269.336 215.041)
(40 . 0.0)
(41 . 0.0)
(42 . 0.0)
(210 0.0 0.0 1.0)
Ejemplos de iteraciones con VLAX-FOR:
LISTADO DE CAPAS
CONTEO DE ENTIDADES:
(setq
cont (1+ cont)
ent (entnext ent) ;devuelve la entidad
que le sigue a ent
) ;_ fin de setq
) ;_ fin de while
cont
;devuelve el valor final
del contador
) ;_ fin de defun
Ms adelante utilizaremos este procedimiento para desarrollar
funciones ms sofisticadas dirigidas a inventariar los objetos
contenidos en un dibujo.
PREDICADO PALINDROMOP OPTIMIZADO:
) ;_ fin de if
(setq cont (1+ cont))
) ;_ fin de while
resultado
) ;_ fin de defun
No basta que un programa alcance los resultados deseados.
Debe hacerlo de manera rpida y eficaz. Este es un principio
que no debe olvidarse.
FUNCIONES DE MAPEADO
Ejemplo de utilizacin de
VLAX-MAP-COLLECTION:
(cond
((null lista) nil)
((apply predicado (list (car lista)))
(cons (car lista)(quitar-si-no predicado (cdr
lista)))
)
(t (quitar-si-no predicado (cdr lista)))
)
)
Tanto es as que se han incorporado como operadores a la
norma de Common LISP bajo los nombres de REMOVE-IF
(QUITAR-SI) y de REMOVE-IF-NOT (QUITAR-SI-NO). Visual
LISP les incorpora el prefijo VL- para distinguirlos de las
funciones del antiguo AutoLISP, y as las encontraremos en el
catlogo de funciones Visual LISP como VL-REMOVE-IF y VLREMOVE-IF-NOT.
Utilizando VL-REMOVE-IF-NOT y con la ayuda de la funcin de
mapeado sobre listas MAPCAR, estudiada en el apartado
anterior, nuestra funcin VertPoly pudiera escribirse de la
siguiente manera:
;;;Funcin VertPoly utilizando VL-REMOVE-IF-NOT
;;;Paso 1:
;;;Eliminar todos las sublistas que no correspondan
al cdigo 10
;;;Paso 2:
;;;Extraer el CDR de cada una de las sublistas.
;;;Se utiliza el mapeado de la funcin CDR a la
lista mediante MAPCAR
;;;Paso 3:
;;;Se aade el valor de la elevacin mapeando a la
lista una expresin LAMBDA.
(defun VertPoly (lista elevacion)
(mapcar
;Paso 3
(function (lambda (x) (append x (list
elevacion))))
(mapcar
;Paso 2
'cdr
(vl-remove-if-not
;Paso 1
(function (lambda (x) (equal (car x)
10)))
lista
) ;_ fin de vl-remove-if-not
) ;_ fin de mapcar
) ;_ fin de mapcar
) ;_ fin de defun
Obsrvese el uso de la funcin FUNCTION que fuerza la
compilacin de las dos expresiones-LAMBDA. Se utiliza en
lugar de QUOTE (o apstrofe) procurando una mayor eficacia y
rapidez.
Esta segunda formulacin resulta ms clara y ms econmica
en cuanto a esfuerzo de programacin. Por otra parte, supera
las limitaciones de Visual LISP en cuanto a la recursin que
pudiera provocar en caso de polilneas con un gran nmero de
vrtices un error por desbordamiento de pila.
Nota: esta funcin devuelve los resultados correctos para
Visual LISP en AutoCAD 2000. Sin embargo hemos
encontrado que falla si se ejecuta desde el IDE Visual LISP
para la versin 14. El error se encuentra en los valores de la
lista de asociacin para el objeto LWPOLYLINE que se
obtienen desde este entorno:
(entget(car(entsel))) aplicado a una LWpolyline en la
lnea de comandos de AutoCAD R14 devuelve:
Command: (entget(car(entsel)))
Select object:
((-1 . <Entity name: 43b0500>) (0 . "LWPOLYLINE") (5
. "20")
(100 . "AcDbEntity") (67 . 0) (8 . "0") (100 .
"AcDbPolyline")
(90 . 7) (70 . 0) (43 . 0.0) (38 . 0.0) (39 . 0.0)
(10 103.882 154.494) (40 . 0.0) (41 . 0.0) (42 .
0.0)
(10 180.771 201.906) (40 . 0.0) (41 . 0.0) (42 .
0.0)
(10 186.224 143.05) (40 . 0.0) (41 . 0.0) (42 . 0.0)
(10 267.476 167.028) (40 . 0.0) (41 . 0.0) (42 .
0.0)
(10 256.569 105.994) (40 . 0.0) (41 . 0.0) (42 .
0.0)
(10 298.558 123.432) (40 . 0.0) (41 . 0.0) (42 .
0.0)
tienen en cuenta objetos con una estructura compleja de listas anidadas. Por
ejemplo, consideremos esta expresin matemtica en formato LISP:
(setq math-formula
'(+ 3 (* (- 5 pi) 4 (/ 3 7))(* 15 2))
)
Math-formula contiene listas dentro de listas dentro de listas.
;; la lista vaca
;; si el primer
;; sumar al
;; si es
;; ignorarlo,
;; o se trata de
;; y sumar al
>(num-nums math-formula)
1> (NUM-NUMS (+ 3 (* (- 5 PI) 4 (/ 3 7)) (* 15
2)))
2> (NUM-NUMS (3 (* (- 5 PI) 4 (/ 3 7)) (* 15
2)))
3> (NUM-NUMS ((* (- 5 PI) 4 (/ 3 7)) (* 15
2)))
4> (NUM-NUMS (* (- 5 PI) 4 (/ 3 7)))
5> (NUM-NUMS ((- 5 PI) 4 (/ 3 7)))
6> (NUM-NUMS (- 5 PI))
7> (NUM-NUMS (5 PI))
8> (NUM-NUMS (PI))
9> (NUM-NUMS NIL)
<9 (NUM-NUMS 0)
<8 (NUM-NUMS 0)
<7 (NUM-NUMS 1)
<6 (NUM-NUMS 1)
6> (NUM-NUMS (4 (/ 3 7)))
7> (NUM-NUMS ((/ 3 7)))
8> (NUM-NUMS (/ 3 7))
9> (NUM-NUMS (3 7))
10> (NUM-NUMS (7))
11> (NUM-NUMS NIL)
<11 (NUM-NUMS 0)
<10 (NUM-NUMS 1)
<9 (NUM-NUMS 2)
<8 (NUM-NUMS 2)
8> (NUM-NUMS NIL)
<8 (NUM-NUMS 0)
<7 (NUM-NUMS 2)
<6 (NUM-NUMS 3)
<5 (NUM-NUMS 4)
<4 (NUM-NUMS 4)
4> (NUM-NUMS ((* 15 2)))
5> (NUM-NUMS (* 15 2))
6> (NUM-NUMS (15 2))
7> (NUM-NUMS (2))
8> (NUM-NUMS NIL)
<8 (NUM-NUMS 0)
<7 (NUM-NUMS 1)
<6 (NUM-NUMS 2)
<5 (NUM-NUMS 2)
5> (NUM-NUMS NIL)
<5 (NUM-NUMS 0)
<4 (NUM-NUMS 2)
<3 (NUM-NUMS 6)
<2 (NUM-NUMS 7)
<1 (NUM-NUMS 7)
7
Sera difcil definir num-nums de forma iterativa. No es imposible, pero exige el
saber utilizar una pila para simular la recursin.
Enviar
Borrar