PARTE TERCERA

MÓDULO ONCE

[1/12]

Programación en AutoLISP

 

ONCE.1. INTRODUCCIÓN

A parte de todo lo visto en cuestión de personalización, AutoCAD 14 ofrece al usuario la posibilidad de crear programas y aplicaciones verticales totalmente funcionales. Estos programas podrán ser distribuidos por el creador, eso sí, siempre correrán bajo AutoCAD.

La capacidad para hacer un programa nos lleva mucho más allá de la simple personalización de menús o patrones de sombreado, nos lleva a un mundo totalmente integrado en AutoCAD desde donde podremos diseñar nuestros propios comandos, manipular dibujos o incluso acceder a la Base de Datos interna del programa.

AutoCAD 14 proporciona diversas interfaces de programación de aplicaciones que vamos a comentar ahora de forma somera.


ONCE.1.1. AutoLISP, ADS, ARX, VBA y Visual Lisp
ONCE.1.1.1. Entorno AutoLISP

Dentro de lo que es la programación existen diversas interfaces para crear programas para AutoCAD. El más antiguo y, quizá el más utilizado hasta ahora, es AutoLISP. AutoLISP es una adaptación del lenguaje de programación LISP que forma parte íntima e integrada con AutoCAD, esto es, AutoCAD posee internamente un propio intérprete de LISP.

El lenguaje LISP está basado en lo que se denominan listas de símbolos. Es un lenguaje de alto nivel (como BASIC) y que, en principio, fue diseñado para la investigación en el campo de la inteligencia artificial. AutoLISP es un lenguaje evaluado, es decir, está a un paso entre los lenguajes interpretados, por un lado, y los lenguajes compilados, por otro.

Como hemos dicho, AutoCAD provee al usuario de un propio intérprete de AutoLISP interno. Este intérprete, al que habría que llamarle evaluador, se encarga —precisamente— de evaluar las expresiones incluidas en el código fuente de un programa. Estos programas pueden introducirse directamente desde la línea de comandos de AutoCAD, o bien cargarse en memoria a partir de un programa completo escrito es un archivo de texto ASCII. Dichos archivos tendrán habitualmente la extensión .LSP.

De la programación en AutoLISP hablaremos largo y tendido en este MÓDULO.


ONCE.1.1.2. Entorno ADS

ADS (AutoCAD Development System) es un entorno de programación el lenguaje C para AutoCAD. Las aplicaciones programadas de esta manera han de ser llamadas desde un propio programa AutoLISP, ya que AutoCAD las considera como funciones externas.

El código fuente de estas aplicaciones ha de escribirse y compilarse en un compilador externo de C, es decir, AutoCAD no provee de un entorno de programación para estas aplicaciones, como ocurre con AutoLISP o VBA. El programa objeto ejecutable .EXE (normalmente), producto de la compilación del fuente, podrá ser cargado desde AutoCAD.

NOTA: Este entorno está ya obsoleto en la versión 14 y los programas desarrollados en él deberán adaptarse a ARX mediante el entorno ADSRX.

 

ONCE.1.1.3. Entorno ARX

ARX (AutoCAD Runtime Extension) es desde la versión 13 de AutoCAD otro entorno de programación C que posibilita, al contrario que ADS, una comunicación directa de las aplicaciones con AutoCAD. De esta forma, no es necesaria la intervención de AutoLISP como intermediario. La aplicación Render, en RENDER.ARX, es un ejemplo de programa en este formato.

La no integración de un entorno de programación en C dentro del software de AutoCAD ha hecho que su utilización para desarrollar aplicaciones para el programa no esté muy extendida. Es necesario, pues, adquirir un compilador de C complementario para poder desarrollar en este lenguaje aplicaciones ADS o ARX, lo que no ocurre con AutoLISP o VBA. Por este motivo, tampoco se tratará en este curso.

NOTA: En la versión 14 de AutoCAD existe el comando ARX para cargar, descargar y obtener información sobre aplicaciones ARX sin necesidad de utilizar AutoLISP.

 

ONCE.1.1.4. Entorno VBA

VBA (Visual BASIC for Applications) es un novedoso entorno, incluido en la versión 14, que parece hacer furor entre los programadores últimamente. La programación en Visual BASIC para Windows viene siendo, desde hace unos años, una de las herramientas más versátiles y, a la vez, más sencillas y utilizadas en el mundo de la programación informática. El usuario puede desarrollar sus programas en un compilador Visual BASIC externo o utilizar el propio módulo VBA que incluye AutoCAD 14. Este módulo contiene la sintaxis del lenguaje, un depurador y un entorno de desarrollo. Así, el programador, puede programar rutinas VBA e ir probándolas en una sesión de AutoCAD mientras se van depurando.

VBA será ampliamente tratado en el MÓDULO DOCE.

 

ONCE.1.1.5. Entorno Visual Lisp

A partir de la Versión 14 existe un nuevo entorno de desarrollo denominado Visual Lisp que permite realizar aplicaciones en AutoLISP de una manera más rápida y efectiva. Este entorno proporciona herramientas para desarrollar y depurar las rutinas y compilarlas como aplicaciones ARX. También dispone de su propio evaluador, que emula al de AutoLISP, además de un completo control de codificación y seguridad de las rutinas creadas.

El entorno de Visual Lisp es un módulo que se carga bajo demanda. No está incluido en el propio núcleo de AutoCAD, como ocurre con el evaluador de AutoLISP. El nuevo conjunto de funciones incorporadas en Visual Lisp permite trabajar en diferentes áreas y niveles que incluyen funciones añadidas de AutoLISP, funciones de acceso al sistema operativo y E/S de archivos, funciones de carga y vinculación de objetos y bases de datos, almacenamiento directo de listas en un archivo de dibujo, acceso al conjunto de objetos ActiveX de AutoCAD y tecnología basada en ObjectARX que no necesita la presencia de AutoCAD para su ejecución.

De esta manera, el entorno de Visual Lisp permite a los desarrolladores la programación en ARX y ActiveX.


ONCE.2. CARACTERÍSTICAS DE AutoLISP

Como ya hemos dicho, LISP (LISt Processing) es un lenguaje de programación que se remonta a los años cincuenta y que fue desarrollado para la investigación de inteligencia artificial. La base de su funcionamiento es el manejo de listas, en lugar de datos numéricos como otros lenguajes. AutoLISP es una implantación LISP en AutoCAD.

Una lista es un conjunto de símbolos. El símbolo es la unidad mínima básica de una lista, y puede ser una variable, una función inherente a AutoLISP, una función de usuario, un dato constante... Las listas elaboradas mediante símbolos son evaluadas y procesadas para obtener un resultado.

Para programar en AutoCAD, este lenguaje proporciona una serie de posibilidades como la facilidad para manejar objetos heterogéneos (números, caracteres, funciones, entidades u objetos de dibujo, etcétera), la facilidad para la interacción en un proceso de dibujo, la sencillez del lenguaje y su sintaxis, y otras que hacen de él una herramienta muy útil y sencilla de manejar y aprender.

Como también hemos dicho ya, el lenguaje AutoLISP (y LISP) es un lenguaje evaluado, y no interpretado o compilado. Los lenguajes interpretados son leídos palabra a palabra por el ordenador, al ser introducidas, y cada una de ellas convertida a lenguaje máquina. Esto hace que sea sencilla su edición y detección de errores de sintaxis u otros; por el contrario, hace que sean muy lentos (ejemplo: Microsoft QBASIC). Los códigos de los lenguajes compilados son escritos por completo y, antes de su ejecución final, es necesario compilarlos, convirtiéndolos así en código fuente ejecutable y comprensible por la máquina. Este tipo de lenguajes hace que su ejecución sea más rápida y pura pero, en contra, resulta más difícil su depuración (ejemplos: Microsoft QuickBASIC o Borland C++).

Los lenguajes evaluados —AutoLISP— están a caballo entre unos y otros. No son tan rápidos como los compilados pero son más flexibles e interactivos que estos. Es posible, por ejemplo, construir un programa con AutoLISP que sea capaz de modificarse a sí mismo bajo determinadas circunstancia; ésta es la base de los llamados Sistema Expertos.

El mecanismo evaluador de AutoLISP es la propia lista: conjunto de símbolos separados entre sí por, al menos, un espacio blanco y encerrados entre paréntesis. Esto es, desde el momento que existe una expresión encerrada entre paréntesis, AutoLISP la evalúa e intenta ofrecer un resultado.

AutoLISP es un subconjunto del lenguaje Common LISP. Como ha sido diseñado para trabajar desde AutoCAD, se han seleccionado las características de LISP más adecuadas para este fin y, además, se han añadido otras nuevas, sobre todo en la manipulación de objetos de dibujo, acceso a la Base de Datos de AutoCAD e interacción gráfica general.

Los programas en AutoLISP son simples archivos de texto ASCII, con la extensión habitual .LSP. Una vez hecho el programa, habremos de cargarlo desde el propio editor de dibujo de AutoCAD. También es posible escribir líneas de código AutoLISP desde la línea de comandos del programa, como veremos en breve.

Es posible la creación de órdenes nuevas que llamen a programas en AutoLISP, así como la redefinición de comandos propios de AutoCAD, como por ejemplo LINEA o DESPLAZA. Pero una de las más importantes potencialidades de AutoLISP es el acceso directo a la Base de Datos interna de AutoCAD. Toda la información de un dibujo, como deberíamos saber, no se guarda como objetos de dibujo en sí, o sea, cuando salvamos un .DWG, en disco no se guardan los círculos, líneas, etcétera, sino una relación o base de datos donde se dice dónde aparece un círculo o una línea, con qué coordenadas de origen y final, con qué radio o diámetro, tipo de línea, color... Podremos pues desde AutoLISP acceder a dicha base de datos para modificarla, editarla o para exportar datos, por ejemplo, a una base de datos externa.

 

ONCE.2.1. Tipos de objetos y datos en AutoLISP

Atendiendo a sus características podemos definir varios tipos de objetos y datos en AutoLISP, que son los de la tabla siguiente:

Objeto o dato ------------------------ Descripción

------------------------------------------------------------------------------------------------------------

Lista ---------------------------------- Objeto compuesto de un paréntesis de aper-
--------------------------------------- tura, uno o más elementos separados por, al
--------------------------------------- menos, un espacio en blanco y un paréntesis
--------------------------------------- de cierre. Los elementos de una lista pueden
--------------------------------------- ser símbolos, valores concretos (constantes
--------------------------------------- numéricas o cadenas) o listas incluidas. Por
--------------------------------------- ejemplo:
(DEFUN seno (x) (SETQ xr (* PI (/x 180.0))) (SETQ
--------------------------------------- s (SIN xr))), se trata de una lista que contiene cinco elemen-
--------------------------------------- tos: una función inherente de AutoLISP
---------------------------------------
DEFUN, un nombre de función de usuario
---------------------------------------
seno, una lista con un único elemento (x) y
--------------------------------------- dos listas
SETQ con tres elementos cada una.

Elemento ----------------------------- Cualquiera de los componentes de una lista.

Símbolo ------------------------------- Cualquier elemento de una lista que no sea
--------------------------------------- una constante. Puede ser el nombre de una
--------------------------------------- variable, un nombre de función definida por
--------------------------------------- el usuario o un nombre de función de AutoLISP.

Enteros ------------------------------- Valores numéricos enteros, sin punto deci-
--------------------------------------- mal. Internamente son números de 32 bits
--------------------------------------- con signo, sin embargo, en la transferencia
--------------------------------------- de datos con AutoCAD son valores de 16 bits
--------------------------------------- con signo, comprendidos por lo tanto entre
--------------------------------------- -32768 y 32767.

Reales -------------------------------- Valores numéricos con coma flotante de do-
--------------------------------------- precisión. Esto representa un mínimo de 14
--------------------------------------- dígitos representativos. Se pueden expresar
--------------------------------------- en notación científica exponencial mediante
e o E.

Cadenas ----------------------------------- Valores textuales que contienen cadenas de
--------------------------------------- caracteres en código ASCII. Deben ir entre
--------------------------------------- comillas y se permite una longitud máxima
--------------------------------------- de 132 caracteres. Se pueden construir cadenas
--------------------------------------- mayores como veremos.

Descriptores de archivo --------------- Valores que representan un archivo abierto
--------------------------------------- para lectura o escritura.

Nombres de objetos de dibujo ---------- Valores que representan el "nombre" hexade-
--------------------------------------- cimal de un objeto de la Base de Datos.

Conjuntos designados de AutoCAD ----- Valores que representan un conjunto de se-
--------------------------------------- lección de objetos de dibujo.

Funciones de usuario --------------------- Símbolo que representa el nombre de una
--------------------------------------- función definida por el usuario.

Función inherente o subrutina ----------- Símbolo con el nombre de una función prede-
--------------------------------------- finida de AutoLISP. Se suelen denominar con
--------------------------------------- la abreviatura inglesa subrs. Pueden ser in-
--------------------------------------- ternas o externas.

 

ONCE.2.2. Procedimientos de evaluación

La base de todo intérprete de LISP es su algoritmo evaluador. Éste analiza cada línea de programa y devuelve un valor como resultado. La evaluación sólo se realizará cuando se haya escrito una lista completa y ésta podrá ser cargada desde un archivo de texto o tecleada directamente en la línea de comandos de AutoCAD 14.

El primer elemento de la lista es comparado con todos los nombres de funciones inherentes base o subrs internas de AutoLISP, con todos los nombres de subrs externas cargadas desde aplicaciones ADS o ARX y en su caso con todos los nombres de funciones de usuario cargadas en memoria. Si el nombre es reconocido, se realiza la evaluación de la expresión de AutoLISP. Esta puede consistir en asignar un valor a una variable, cargar en memoria una función de usuario, escribir un resultado en pantalla o en un archivo, dibujar un objeto gráfico, etc.

El primer elemento de la lista debe ser por tanto un nombre de función. El resto de elementos se consideran argumentos de dicha función. La evaluación en AutoLISP se realiza de acuerdo a las siguientes reglas.

Primera:

Las listas se evalúan quedando determinadas por el primer elemento. Si éste es un nombre de función inherente o subrutina, los elementos restantes de la lista son considerados como los argumentos de esa función. En caso contrario se considera como un nombre de función definida por el usuario, también con el resto de elementos como argumentos. Cuando los elementos de una lista son a su vez otras listas, éstas se van evaluando desde el nivel de anidación inferior (las listas más "interiores"). El valor resultante en cada evaluación de las listas "interiores", es utilizado por las listas "exteriores". Por ejemplo:

(SETQ sx (SIN (* PI (/ x 180.0))))

La lista más "interior" contiene como primer elemento el nombre de la función de AutoLISP / que realiza el cociente o división del siguiente elemento entre los restantes. La evaluación de dicha lista devuelve el resultado del cociente, en este caso el valor contenido en la variable x dividido entre el número real 180.0. Dicho valor es utilizado como elemento en la lista circundante que empieza por la función de AutoLISP * que realiza una multiplicación o producto. Esta lista se evalúa ofreciendo como resultado el producto de PI (3,14159) por el valor anterior. A su vez el resultado interviene como argumento en la lista que empieza por la función de AutoLISP SIN, que es evaluada obteniéndose el seno. Este interviene por último como argumento de la lista más exterior que empieza por la función de AutoLISP SETQ , cuyo resultado es asignar o almacenar en la variable sx el valor del seno. Este valor es devuelto por la lista de SETQ como resultado final.

Segunda:

Puesto que cada lista contiene un paréntesis de apertura y otro de cierre, cuando existen listas incluidas en otras, todos los paréntesis que se vayan abriendo deben tener sus correspondientes de cierre. Si se introduce desde el teclado una expresión en AutoLISP a la que falta por cerrar algún paréntesis, se visualiza un mensaje del tipo n> donde n es un número que indica cuántos paréntesis faltan por cerrar. Se pueden introducir por teclado esos paréntesis y subsanar el error. Por ejemplo:

Comando: (SETQ sx (SIN (* PI (/ x 180.0))
2> ))
0.523599


Tercera:

También es posible evaluar directamente un símbolo (extraer por ejemplo el valor actual contenido en una variable), introduciendo por teclado el signo de cerrar admiración seguido del nombre del símbolo. Esta evaluación se puede producir incluso en mitad de un comando. Por ejemplo, para suministrar como ángulo para un arco el valor contenido en la variable x, se responde a la solicitud de AutoCAD con !x. Por ejemplo:

Comando: !sx
0.523599


Cuarta:


Los valores enteros, reales, cadenas de texto y descriptores de archivos, devuelven su propio valor como resultado. Los nombres de funciones inherentes o subrutinas de AutoLISP devuelven un número interno hexadecimal (suele cambiar de una sesión de dibujo a otra). Por ejemplo:

!72.5 devuelve 72.5
!"Inicio"
devuelve "Inicio"
!SETQ
devuelve <Subr: #1a93e24>


Quinta:

Los símbolos de variables participan con el valor que contienen (que les está asociado) en el momento de la evaluación. Por ejemplo:

!x devuelve 30
!sx
devuelve 0.523599


Sexta:

Determinadas funciones de AutoLISP pueden devolver un valor nulo, que se representa mediante la expresión nil. Por ejemplo:

Comando: (PROMPT "Bienvenido a AutoLISP\n")
Bienvenido a AutoLISP
nil

La función PROMPT escribe en la línea de comando el mensaje especificado y devuelve nil. El código \n equivale a INTRO.

 

ONCE.2.3. Archivos fuente de programas

Las expresiones contenidas en un programa de AutoLISP pueden introducirse directamente desde el teclado durante la edición de un dibujo de AutoCAD, escribirlas en un fichero de texto ASCII o ser suministradas por una variable del tipo cadena, como ya se ha dicho varias veces.

Para una correcta evaluación, las expresiones deben cumplir unos requisitos de sintaxis, que se pueden resumir en los siguientes puntos:

— Una expresión puede ser tan larga como se quiera. Puede ocupar varias líneas del archivo de texto.

— Los nombres de símbolos pueden utilizar todos los caracteres imprimibles (letras, números, signos de puntuación, etc.) salvo los prohibidos que son: ( ) . ' " ;

— Los nombres de símbolos no son sensibles a las mayúsculas. Así, seno y SENO representan el mismo nombre. Los nombres pueden contener números, pero no estar formados exclusivamente por números. Así, 1pt, pt-1, p12 son válidos como nombres de variables, pero no 21, que será interpretado como un valor numérico constante.

— Los caracteres que terminan un nombre de símbolo o un valor explícito (una constante numérica o de texto) son: paréntesis de apertura y cierre, apóstrofo, comillas, punto y coma, espacio en blanco o final de línea en el archivo. Estos caracteres sirven de separación entre elementos de una lista.

— Los espacios en blanco de separación entre símbolos son interpretados como un solo espacio entre cada par de símbolos. Se recuerda que es necesario un espacio en blanco para separar un símbolo del siguiente, siempre que no haya paréntesis, apóstrofo, comillas o punto y coma. Debido a la longitud de las expresiones de AutoLISP y a la profusión de paréntesis que dificultan su lectura, suele ser norma habitual realizar sangrados en las líneas del archivo de texto, para resaltar los paréntesis interiores de los exteriores. Todos los espacios añadidos son interpretados como uno solo.

—Los valores explícitos (constantes) de números pueden empezar con el carácter + o - que es interpretado como el signo del número.

— Los valores de constantes de números reales deben empezar con una cifra significativa. El carácter punto (.) se interpreta como el punto decimal. También se admite + o - para el signo y e o E para notación exponencial o científica. No es válida la coma decimal, ni tampoco abreviar como en .6 (hay que escribir 0.6).

— Los valores de constantes con cadenas de texto son caracteres que empiezan y terminan por comillas. Dentro de las cadenas se pueden incluir caracteres de control mediante la contrabarra (\). Los códigos permitidos son:

\\ ------ Carácter contrabarra (\).

\" ------ Carácter comillas (").
\e ------ Carácter de escape.
\n ------ Nueva línea o retorno de carro.
\r ------ INTRO
\t
------ Carácter de tabulador TAB
\nnn
------ Carácter cuyo código octal (no ASCII, que es decimal) es nnn.
\U+xxxx ------ Secuencia de caracteres de código Unicode.
\M+nxxxx ------ Secuencia de caracteres multibyte.

Los códigos deben ir en minúsculas. Para incluir en una cadena un código ASCII hay que calcular su valor octal. Por ejemplo, el carácter dólar $ es ASCII 36; su valor octal será 44 y en la cadena habrá que indicar el código de control \44.

— El apóstrofo (’) se puede utilizar como abreviatura del comando QUOTE. El comando QUOTE devuelve el literal del símbolo. Es decir, cuando en una expresión un símbolo aparece precedido por apóstrofo o se le aplica la función de AutoLISP QUOTE, no se evalúa con el valor que contiene en ese momento sino que devuelve el propio nombre literal del símbolo.

— Se pueden incluir comentarios en un archivo de texto con programas y expresiones en AutoLISP, comenzando la línea del archivo con un punto y coma (;). A partir de donde se encuentre un punto y coma hasta el final de la línea, AutoLISP considera que son comentarios y no los tiene en cuenta. También se pueden incluir comentarios en mitad de una línea u ocupando varias de ellas, si se sitúan entre los caracteres ;| y |;. Por ejemplo:

;Función de estado actual del dibujo.
(DEFUN funcion_1 (x / pt1 pt2)
(SETQ refnt0 ;| modos de referencia actualmente
activados |; (GETVAR "osmode"))
...

Los comentarios son útiles tanto para el autor del programa como para futuros usuarios que accedan al archivo con el fin de modificarlo. Suele ser habitual situar al principio del archivo el título, autor y fecha de creación. Posteriormente, una explicación general del programa, explicaciones particulares de cada función intermedia, usos de variables, etc. Como muchas de las configuraciones de pantalla de texto disponen de un ancho de 80 columnas, conviene que las líneas del archivo de texto no sobrepasen los 80 caracteres.

 

ONCE.2.4. Variables predefinidas

Existen unos valores de símbolos de AutoLISP predefinidos. Son los siguientes:

· PI. Es el valor del número real PI, es decir: 3,141592653589793.

· PAUSE. Es una cadena de texto que consta de un único carácter contrabarra. Se utiliza para interrumpir un comando de AutoCAD después de haberlo llamado mediante la función de AutoLISP COMMAND. Esto permite al usuario introducir algún dato.

· T. Es el símbolo de True, es decir, cierto o verdadero (valor 1 lógico). Se utiliza para establecer que determinadas condiciones se cumplen.

· Por último el valor de nada, vacío o falso (0 lógico) se representa en AutoLISP por nil. Este valor aparece siempre en minúsculas y no es propiamente un símbolo, ya que no está permitido acceder a él.

 

ONCE.3. PROGRAMANDO EN AutoLISP

A partir de ahora vamos a comenzar a ver poco a poco la manera de ir haciendo nuestros programas en AutoLISP. Vamos a seguir un orden lógico de menor a mayor dificultad, por lo que la estructura puede llegar a parecer un poco caótica para alguien que conozca el lenguaje. Tampoco es objetivo de este curso profundizar en un método complejo de programación, sino proponer unas bases para comenzar a programar que, con imaginación y horas de trabajo, podrá convertirnos en programadores expertos de AutoLISP.

Todo lo visto hasta ahora resulta la parte árida de la programación; parece que no sirven de mucho esos conocimientos teóricos mientras no pasemos a la práctica. De aquí en adelante podremos ir entendiendo las 2 primeras secciones de este MÓDULO y, si algo se quedó en el tintero o algo hay que repetir de todo lo expuesto hasta aquí, se completará y se explicará o repetirá.

Comencemos, pues, con la programación en AutoLISP para AutoCAD 14.


ONCE.3.1. Convenciones de sintaxis

Las convenciones utilizadas para las sintaxis en este MÓDULO van a ser las siguientes:


·
Nombre del comando o función AutoLISP en mayúsculas.

· Argumentos en minúscula itálica, representados por un nombre mnemotécnico.

· Argumentos opcionales encerrados entre corchetes itálicos (que no han de escribirse).

· Puntos suspensivos en itálica indican la posibilidad de indicar más argumentos.

 

ONCE.4. OPERACIONES NUMÉRICAS Y LÓGICAS

Explicaremos aquí la manera en que se realizan en AutoLISP las operaciones matemáticas, de comparación y lógicas. El buen aprendizaje de estás técnicas nos será tremendamente útil a la hora de lanzarnos a la programación pura.

 

ONCE.4.1. Aritmética básica

Para realizar las cuatro operaciones aritméticas básicas existen cuatro funciones AutoLISP que son +, -, * y /, estas se corresponden con la suma, resta, multiplicación y división.

La función de suma tiene la siguiente sintaxis:

(+ [valor1 valor2 valor3...])

Esto es, primero se indica el nombre de la función, como siempre en AutoLISP, que en este caso es + y luego los argumentos de la misma, es decir, aquí los valores de los distintos sumandos.

Esta función devuelve el resultado aditivo de todos los valores numéricos especificados como argumentos de la función. Por ejemplo:

(+ 14 10 20)

devolvería el valor 44. Para hacer la prueba únicamente debemos escribir dicho renglón en la línea de comandos de AutoCAD, pulsar INTRO y comprobar el resultado.

NOTA: Al introducir el primer carácter de apertura de paréntesis, AutoCAD reconoce que se está escribiendo una expresión en AutoLISP, por lo que nos permitirá utilizar los espacios necesarios de la sintaxis sin que se produzca un INTRO cada vez, como es habitual. Recordemos que todos los elementos de una lista de AutoLISP han de ir separados por lo menos con un espacio blanco. Probemos diferentes sintaxis utilizando más espacios, o tabuladores, y comprobemos que el resultado es el mismo; se interpretan los espacios o tabuladores como un único carácter de espacio en blanco.

NOTA: Hagamos la prueba de no introducir el paréntesis final de la lista indicada. Comprobaremos lo explicado en la segunda regla de la sección ONCE.2.2.

Con la función + podemos indicar valores enteros o reales. Si todos los valores son enteros el resultado será entero, pero si uno o varios de ellos son reales —o todos ellos—, el resultado será real. Esto significa que únicamente es necesario introducir un valor real para recibir una respuesta real. Por ejemplo, si introducimos la siguiente línea en la línea de comandos en AutoCAD:

(+ 14 10 20.0)

el resultado será:

44.0

o sea, un número real.

Esto aquí parece irrelevante, pero comprenderemos su utilidad al hablar, por ejemplo, de la división.

Si indicamos un solo sumando con esta función, el resultado es el valor del propio sumando. Por ejemplo:

(+ 23)

devuelve:

23


Y si se escribe la función sin argumentos, el resultado es
0 (función sin argumentos: (+)).

Los valores indicados en la función de suma pueden ser directamente valores numéricos o nombres de variables numéricas declaradas anteriormente, por ejemplo:

(+ 10.0 x total)

En esta función, 10.0 es un valor constante real y x y total son dos nombres de variables que han debido ser anteriormente declaradas; ya aprenderemos a declarar variables. Si la variable no existiera se produciría un error bad argument type de AutoLISP.

Otros ejemplos con números negativos:

(+ 10 –23) devuelve –13
(+ -10 –10)
devuelve -20

NOTA: Si se produce algún error de sintaxis u otro, podemos acudir al final de este MÓDULO para ver una relación de los mensajes de error de AutoLISP.

La función de resta, por su lado, tiene la siguiente sintaxis:

(- [valor1 valor2 valor3...])

Esta función devuelve la diferencia del primer valor con todos los demás indicados. Así por ejemplo:

(- 10 5)

da como resultado 5 y la siguiente expresión:

(- 10 5 2)


da como resultado
3. Esto es producto de restar 10 – 5 = 5 y, luego, 5 – 2 = 3; o lo que es lo mismo 10 – (5 + 2) = 3.

Al igual que en la suma, si se indican valores enteros el resultado será entero, si se indica uno real (con uno es suficiente) el resultado es real, si se indica un solo valor se devuelve el mismo valor y si se escribe la función sin argumentos se devuelve 0. Así pues, si queremos un resultado real efectuado con números enteros para posteriores operaciones, deberemos indicar uno de los valores entero; de la siguiente manera, por ejemplo:

(- 10 5.0 2)

o cualquier otra combinación posible de uno o más números enteros.

Como se ha explicado para la suma, los valores de los argumentos para la resta pueden ser constantes, eso sí, siempre numéricas, o variables:

(- tot num1 num2)

Llegados a este punto, podemos suponer ya las diferentes combinaciones que podremos realizar con las distintas funciones aritméticas. Por ejemplo, es factible la evaluación de la siguiente expresión:

(+ 12 (- 2 -3))

cuyo resultado es 11. O sea, y como hemos explicado, se realizarán las operaciones de dentro a fuera. En este ejemplo, se suma la cantidad de 12 a la diferencia 2 – 3, esto es, 12 + (2 – 3) = 11. Como vemos, existen dos listas, una interior anidada a la otra que es, a la vez, argumento de la lista exterior. Ocurre lo mismo con nombres de variables:

(- fer1 (+ -sum1 sum2) 23.44)

Con respecto al producto su sintaxis es la siguiente:

(* [valor1 valor2 valor3...])

Se evalúa el producto de todos los valores numéricos indicados como argumentos. Como anteriormente, si un valor es real el resultado es real. Un solo valor como argumento devuelve el mismo valor. Ningún valor devuelve 0. Veamos un ejemplo:

(* 12 3 4 -1)

El resultado es -144. Veamos otros ejemplos:

(* 2 3)
(* val (- vax vad))
(- (* 12 2) 24)
(+ (- -10 -5) (* 3 total 23))


NOTA: Si escribimos más paréntesis de los necesarios por la derecha se nos mostrará un mensaje de error. Recordar que si no los escribimos nos da la opción de escribirlos después, así como el número de ellos que faltan. De todas forma, consúltese el final del MÓDULO para la explicación de los mensajes de error.

La sintaxis de la división es la que sigue:

(/ [valor1 valor2 valor3...])

La función / realiza el cociente del primer valor numérico por todos los demás, es decir, divide el primer número por el producto de los demás. Por ejemplo:

(/ 10 2)

da como resultado 5. Y el ejemplo siguiente:

(/ 100 5 5)

da como resultado 4, es decir, 100 / 5 = 20 y, luego, 20 / 5 = 4; o lo que es lo mismo, 100 / (5 * 5) = 4.

Otros dos ejemplos:

(/ 24 (* (+ 10.0 2) 12))
(/ 12 2 1)

Con respecto al cociente debemos realizar las mismas observaciones anteriores, esto es, si se indica un solo valor se devuelve el mismo valor, si se indica la función sin argumentos se devuelve 0 y si se indican valores enteros sólo se devuelven valores enteros. Esto último cobra especial sentido en el caso de las divisiones, ya que el cociente entre dos números enteros puede ser un número real. Veamos el siguiente ejemplo:

(/ 15 7)

Si introducimos esta línea el resultado será 2. El motivo es que, como hemos especificado valores enteros, el resultado se muestra en forma de número entero, con la parte decimal o mantisa truncada. Para asegurarnos de recibir una respuesta correcta (con decimales significativos), deberemos introducir uno de los valores —o todos ellos, pero con uno es suficiente— como valor real, de la siguiente forma:

(/ 15 7.0)

Ahora el resultado será 2.14286. El número entero podría haber sido el otro:

(/ 15.0 7)

Esto debemos tenerlo muy en cuenta a la hora de realizar operaciones cuyo resultado vaya a ser parte integrante de otra operación —o no— que puede devolver decimales. Vemos otros ejemplos de divisiones:


(/ -12.0 7.8 210)
(/ (+ (- 23.3 32) 12.03) (/ (* (+ 1.01 2.01) 100)))
(+ datos (/ grupo (* 100 2)))

NOTA: Evidentemente, la división por 0 produce un error de AutoLISP: divide by zero.

 

1ª fase intermedia de ejercicios

· Realizar mediante AutoLISP las siguientes operaciones aritméticas (están expresadas en notación informática sencilla de una línea):

(50 + 5) / 2
(200 * 5 – 3) / (4 / 2)
(10.23 – (12.03 / 3)) * (12 + (2 * -2) – ((12.5 / 2) * 2.65))
(19 + 23) / (10 + (23 / (23 / 19)))
((-20 / 5) – 1) / (15.5 * ((15.5 – 1) / 12))

 

ONCE.4.2. Matemática avanzada

Fuera aparte de las funciones aritméticas de nivel básico, programando en AutoLISP podemos realizar operaciones matemáticas complejas como raíces cuadradas o senos. Vamos a explicar aquí las funciones que controlan estas operaciones.


Las dos primeras que veremos son sencillas de entender y utilizar. Ambas se refieren al incremento, positivo o negativo, de una unidad a un valor numérico.

(1+ valor)

Esta sintaxis corresponde a la función de incremento positivo de una unidad al valor indicado. Así, si queremos incrementar en 1 el valor 576, haremos:

(1+ 576)

Esto equivale a (+ 576 1) pero es de una forma más cómoda; el resultado es 577.

NOTA: La función se denomina 1+ en sí, por lo que no existe espacio entre 1 y +.

Podemos realizar estos incrementos con nombres de variable:

(1+ n)

lo que incrementará en una unidad el valor de n. Esto puede ser especialmente necesario para controlar los llamados contadores-suma en programación, del tipo:

(SETQ sum (1+ sum))

Esto ya lo veremos a la hora de declarar variables.

La siguiente función resta (incremento negativo) una unidad al valor numérico indicado. Equivale a (- valor 1), pero de una forma más cómoda.

(1- valor)

Por ejemplo:

(1- 32)

suyo resultado es 31.

Otros ejemplos de estas dos funciones:

(1- n)
(1- 67.90)
(1- -23)
(1+ -34.0)
(1+ (+ tuttot 1)
(1- (* 2 2))
(1- (* (/ 32 2) (+ 10 1.0)))

(ABS valor)

Esta función ABS devuelve el valor absoluto del número indicado o expresión indicada. De esta forma, la siguiente expresión:

(ABS –23)

devuelve 23.

Las siguientes expresiones tienen el siguiente efecto indicado:

(ABS –25.78) devuelve 25.78
(ABS 45)
devuelve 45
(ABS 0)
devuelve 0
(ABS –13)
devuelve 13
(ABS (/ 2 3.0))
devuelve 0.666667
(ABS (/ 2 -3.0))
devuelve 0.666667

(FIX valor)

FIX trunca un valor a su parte entera (positiva o negativa), es decir, de un número real con decimales devuelve únicamente su parte entera. Pero, cuidado, no se produce redondeo, sólo un truncamiento.

Ejemplos:

(FIX 32.79) devuelve 32
(FIX –12.45)
devuelve –12
(FIX (/ 10 3.0))
devuelve 3
(FIX (/ 10 –3.0))
devuelve –3

(REM valor1 valor2 [valor3...])

Esta función AutoLISP devuelve el resto del cociente (módulo) de los dos valores introducidos en principio. Por ejemplo, la siguiente expresión devuelve 6 como resultado:

(REM 20 7)

Dicho 6 es el resto que resulta de dividir 20 / 7. Si aplicamos la regla de la división (dividendo es igual a divisor por cociente más resto): 20 = 7 * 2 + 6, vemos que se cumple correctamente.

Si se especifican más de dos valores, el resto anterior es dividido entre el actual, devolviendo el nuevo resto de la nueva división. Por ejemplo:

(REM 20 7 4)

da como resultado 2. El primer resto 6 se calcula de la forma explicada en el ejemplo anterior y, el resultado final 2, se produce al dividir dicho primer resto entre el tercer valor 4. Al dividir 6 / 4, nos da un resultado (que es igual a 1) y un resto 2 (valor final obtenido). Y así sucesivamente.

Otros ejemplos:

(REM –1 2)
(REM 0 23)
(REM (* 23 2) (- (+ 1 1) 45.5))
(REM 54 (* 3 -4))

Pasemos ahora a ver las funciones trigonométricas, esto es, cómo calcularlas mediante AutoLISP. La primera sintaxis se refiere al seno de un ángulo y es la siguiente:

(SIN ángulo)

La función SIN devuelve el seno de un ángulo expresado en radianes. Ejemplos:

(SIN 1) devuelve 0.841471
(SIN (/ PI 2))
devuelve 1.0

NOTA: Como sabemos PI es un constante de AutoLISP, por lo que no hace falta declararla como variable; ya tiene valor propio y es 3.14159. Aún así, se puede calcular su valor exacto mediante la expresión: PI = 4 * arctag 1.

(COS ángulo)

COS devuelve el coseno de un ángulo expresado en radianes. Ejemplos:

(COS PI) devuelve –1.0
(COS (* 3 4))
devuelve 0.843854

NOTA: Nótese que PI es un valor real, por lo que el resultado será real.

(ATAN valor1 [valor2])

Esta función ATAN devuelve el arco cuya tangente es valor1 expresada en radianes, es decir, realiza el arco-tangente de dicho valor. Por ejemplo:

(ATAN 1.5) devuelve 0.98

Si se indica un segundo valor (valor2), ATAN devuelve el arco-tangente de valor1 dividido por valor2. Esto permite indicar la razón entre los lados de un triángulo recto, es decir, escribir la tangente directamente como cociente del seno entre el coseno. Si valor2 es 0, el valor devuelto será igual a PI / 2 o a –PI / 2 radianes, dependiendo del signo de valor1.

Ejemplos:

(ATAN 1 1)
(ATAN 1 (* 2 -4.5))

Estas son las tres funciones trigonométricas de AutoLISP. En este punto se nos plantean un par de problemas: ¿cómo calculo las restantes funciones trigonométricas? y ¿cómo convierto grados sexagesimales en radianes y viceversa?

La segunda cuestión es sencilla, ya que basta aplicar al fórmula rad = grados * PI / 180 para convertir grados en radianes. La operación inversa en fácilmente deducible.

La primera pregunta tiene una respuesta no menos sencilla, y es que en la mayoría —por no decir todos— de los lenguajes de programación únicamente nos proporcionan estas funciones trigonométricas básicas y, a partir de ellas, podemos calcular las funciones trigonométricas derivadas inherentes. La manera se explica a continuación mediante notación sencilla de una línea:

Función derivada --------- Notación

-------------------------------------------------------------------------------------

Secante (sec x) ------------ 1 / cos (x)
Cosecante (cosec x) ------- 1 / sen (x)
Arco-seno (arcsen x) ------- arctag (x /
Ö (1 – x ^ 2))
Arco-coseno (arccos x) ----- 1.5707633 – arctag (x /
Ö (1 – x ^ 2))
Arco-secante (arcsec x) ---- arctag (
Ö (x ^ 2 – 1)) + signo (x) –1) * 1.5707633
Arco-cosecante (arccos x) -- arctag (1/
Ö (x ^ 2 – 1)) + signo (x) –1) * 1.570763
Arco-cotang. (arccotag x) --- 1.5707633 – arctag (x)

NOTA: El símbolo ^ significa exponenciación. Ö es raíz cuadrada. signo (x) se refiere al signo del valor; si éste es positivo signo (x) valdrá 1, si es negativo valdrá –1 y si es cero valdrá 0. No debemos preocuparnos ahora por esto, ya que aprenderemos en breve o más adelante —con mayor soltura— a realizar exponenciaciones, raíces cuadradas y operaciones con signos.

Sigamos, pues, ahora con otras diferentes funciones que nos ofrece AutoLISP a la hora de realizar operaciones matemáticas. La siguiente dice referencia a las raíces cuadradas; su sintaxis es:

(SQRT valor)

Esta función devuelve el resultado de la raíz cuadrada del valor indicado, ya sea un guarismo simple o una expresión matemática, como siempre. Así por ejemplo, veamos unas expresiones con sus correspondientes evaluaciones:

(SQRT 4) devuelve 2.00
(SQRT 2)
devuelve 1.4142
(SQRT (* 2 6))
devuelve 3.4641

La intención de extraer una raíz cuadrada de un número negativo produce el error function undefined for argument de AutoLISP.

Por otro lado, la sintaxis para la función exponencial es la siguiente:

(EXPT base exponente)

EXPT devuelve el valor de base elevado a exponente. De esta forma, para elevar 5 al cubo (igual a 125), por ejemplo, escribiremos:

(EXPT 5 3)

Otro ejemplo:

(EXPT 2.3 7.23)

De esta forma, como sabemos, podemos resolver el resto de raíces (cúbicas, cuartas, quintas...) existentes. Ya que raíz cúbica de 32 es lo mismo que 32 elevado a 1 / 3, podemos escribir la siguiente expresión:

(EXPT 32 (/ 1 3))

Así también:

(EXPT 20 (/ 1 5))
(EXPT 10 (/ (+ 2 4) (- v23 rt sw2))
(EXPT 3 (/ 1 2))

NOTA: El intento de extraer raíces negativas de cualquier índice producirá el mismo error explicado en SQRT.

 

(EXP exponente)

Esta función devuelve la constante (número) e elevada al exponente indicado. Se corresponde con el antilogaritmo natural. Por ejemplo:

(EXP 1) devuelve 2.71828

(LOG valor)

LOG devuelve el logaritmo neperiano o natural (en base e) del valor indicado. Por ejemplo:

(LOG 4.5) devuelve 125.0000

(GCD valor_entero1 valor_entero2)

Esta sintaxis se corresponde con la función de AutoLISP GCD, que devuelve el máximo común denominador de los dos valores indicados. Estos valores han de ser obligatoriamente enteros, de no ser así, AutoLISP devuelve bad argument type como mensaje de error. Veamos unos ejemplos:

(GCD 45 80) devuelve 5
(GCD 80 70)
devuelve 10
(GCD (* 10 10) (/ 70 2))
devuelve 5

Si se indica un entero negativo el mensaje de error de AutoLISP es improper argument.

Las dos últimas funciones matemáticas que veremos pueden sernos de gran ayuda a la hora de programar. Una de ellas (MAX) devuelve el mayor de todos los números indicados en la lista. Su sintaxis es:


(MAX valor1 valor2...)

Los valores pueden ser números enteros o reales, y también expresiones matemático-aritméticas. Así por ejemplo:

(MAX 78.34 –12 789 7)

devolverá 789.0, ya que es el número mayor. Lo devuelve como real por la aparición de decimales en el elemento 78.34. Como sabemos, con la sola aparición de un valor real en una lista, el resultado es real.

Si el elemento mayor de la lista es un expresión matemática, se devolverá su resultado, no la expresión en sí, por ejemplo:

(MAX (* 10 10) 5)

devolverá 100 como resultado (10 * 10).

Otro ejemplo:

(MAX –5 –7 –9)

devolverá –5.

(MIN valor1 valor2...)

La función MIN, por su lado, devuelve el menor de todos los valores indicados en lista. Las demás consideraciones son análogas a la función anterior. Ejemplos:

(MIN 1 2 3 4 7) devuelve 1
(MIN 23.3 7 0)
devuelve 0.0
(MIN (/ 7 3) 0.56)
devuelve 0.56


Ejemplos de
MAX y MIN con variables:

(MIN x y z)
(MIN (+ x1 x2) (+ y1 y2) (+ w1 w2) (+ z1 z2))

Y hasta aquí todas las funciones que tienen que ver con operaciones matemáticas. Pasaremos, tras unos ejercicios propuestos, a ver las operaciones de comparación, muy interesantes y sencillas de comprender.

 

2ª fase intermedia de ejercicios

· Realizar mediante AutoLISP las siguientes operaciones matemáticas (están expresadas en notación sencilla de una línea):

Ö ((20 – 3) * (8 – 2))
1 + 78.8 + ((78.8 ^ 2) / 2) + ((78.8 ^ 3) / 3)
(sen (Ö (80 * 28.002) – cos (PI / 2))) / (PI – (1 / 2))
arccos (100 / 2)
(124.6589 * (e ^ 2.3)) / (7 * Ö 2)
ln (45 * (7 / 2))
(23.009 / 78.743) ^ (56.00123 – 1)

· Realícense ejercicios de cálculo de valores mayores y menores de listas, así como de máximos comunes denominadores.

· Realizar un par de ejercicios de incremento y decremento de una unidad a valores.

NOTA: Las operaciones en general siguen en AutoLISP la jerarquía de las operaciones matemáticas: paréntesis internos, paréntesis externos, operadores unitarios (signos), potenciación, multiplicación y división, suma y resta, operadores relacionales (mayor que, menor que...) y operadores lógicos (álgebra de Boole). Y cuando existen varios operadores en el mismo nivel, se ejecutan de izquierda a derecha. Ahora mismo veremos operadores relacionales o de comparación y, luego, el álgebra de Boole en AutoLISP.

 

ONCE.4.3. Operaciones relacionales

Las funciones que veremos a continuación se denominan relacionales o de comparación, y es que comparan valores, ya sean numéricos o textuales (cadenas) emitiendo un resultado verdadero o falso, según la comparación. Estas funciones son conocidas por todos (igual, mayor que, menor o igual que...), sólo queda determinar cómo se utilizan y cuál es su sintaxis en AutoLISP.

Como hemos dicho el resultado de la evaluación solo puede ser uno de dos: T (True) que representa el verdadero o cierto, o nil que representa el falso o nulo.

NOTA: Con la devolución nil por parte de AutoLISP nos empezamos a familiarizar ahora y la veremos muchas veces.

Comencemos por el igual o igual que, cuya sintaxis es la siguiente:

(= valor1 [valor2...])

La función = compara todos los valores especificados —uno como mínimo—, devolviendo T si son todos iguales o nil si encuentra alguno diferente. Los valores pueden ser números, cadenas o variables (numéricas o alfanuméricas). Así por ejemplo:

(= 5 5) devuelve T
(= 65 65.0)
devuelve T
(= 7 54)
devuelve nil
(= 87.6 87.6 87.6)
devuelve T
(= 34 34 –34 34)
devuelve nil


Veamos ahora algún ejemplo con cadenas:

(= "hola" "hola") devuelve T
(= "casa" "cAsa")
devuelve nil
(= "H" "H" "H" "H")
devuelve T
(= "hola ahora" "hola ahora")
devuelve nil


NOTA: Nótese, como adelanto, que las cadenas literales han de ir encerradas entre comillas, como en casi todos los lenguajes de programación.


Con variables declaradas, que ya veremos, sería de la misma forma. Si sólo se indica un valor en la lista, AutoLISP devuelve
T.

NOTA: Hay que tener en cuenta que esta función sólo compara valores y no listas o expresiones. Si, por ejemplo, se tienen dos variables pt1 y pt2 con dos puntos que son listas de tres elementos (una coordenada X, una coordenada Y y una coordenada Z), para comparar la igualdad de ambos habría que recurrir a una función lógica como EQUAL, que veremos un poco más adelante.

(/= valor1 [valor2...])

 

Esta función /= (distinto o desigual que) devuelve T si alguno o algunos de los valores comparados de la lista son diferentes o distintos de los demás, por ejemplo en los siguientes casos:

(/= 2 3)
(/= "texto" "textos")
(/= (* 2 2) (* 2 4) (* 2 3)

Devuelve nil si todos los valores son iguales, por ejemplo:

(/= "casa" "casa" "casa")
(/= "1 2 3" "1 2 3" "1 2 3" "1 2 3" "1 2 3")
(/= 32 32 32 32)
(/= (* 10 10) (* 25 4))

Si únicamente se indica un valor, AutoLISP devuelve T.

(< valor1 [valor2...])

Esta sintaxis se corresponde con la comparación menor que. Es una función AutoLISP que devuelve T si efectivamente el primer valor comparado es menor que el segundo. Si existen diversos valores, cada uno ha de ser menor que el siguiente para que AutoLISP devuelva T. Si no se devuelve nil. Veamos algunos ejemplos:

(< 2 3) devuelve T
(< 3 4 5 89 100)
devuelve T
(< 3 –4 5 6)
devuelve nil
(< (* 2 2) (/ 5 3))
devuelve nil

En el caso de cadenas o variables alfanuméricas (las que contienen cadenas), la comparación se efectúa según el valor de los códigos ASCII. Por lo tanto, será el orden alfabético ascendente (de la A a la Z) la manera de considerar de menor a mayor los caracteres, teniendo en cuenta que el espacio blanco es el carácter de menor valor y que las letras mayúsculas son de menor valor que las minúsculas. Ejemplos:

(< "a" "b") devuelve T
(< "z" "h")
devuelve nil
(< "A" "a" "b")
devuelve T
(< "f" "S")
devuelve nil

Si las cadenas tienen más caracteres se comparan de la misma forma:

(< "abc" "abd") devuelve T
(< "abc" "ab")
devuelve nil

No es posible comparar cadenas literales con números; AutoLISP devuelve un mensaje de error que dice bad argument type. Con variables que contienen valores numéricos o literales se realizaría de la misma manera:

(< valor1 valor2 total)
(< -12 –7 km hrs)
(< autor1 autor2 autor3 auto4 autor5)

(<= valor1 [valor2...])

Esta es la función menor o igual que. Funciona de la misma forma que la anterior pero teniendo en cuenta que devolverá T si cada valor es menor o igual que el anterior. Si no devolverá nil. He aquí unos ejemplos:

(<= 10 30 30 40 50 50) devuelve T
(<= 12.23 12.23 14)
devuelve T
(<= 56 57 57 55)
devuelve nil

Las demás consideraciones son idénticas a las de la función precedente.

(> valor1 [valor2...])

Al igual que en la comparación de menor que, pero de manera inversa, esta función devuelve T si cada valor especificado, sea numérico sea cadena, es mayor que el siguiente, esto es, si se encuentran ordenados de mayor a menor. Si no devuelve nil. Por ejemplo:

(> 10 5 4.5 –2) devuelve T
(> "z" "gh" "ab")
devuelve T
(> 23 45)
devuelve nil

Otros ejemplos:

(> saldo divid)
(> pplanta ppiso pcubierta)

(>= valor1 [valor2...])

Similar a los anteriores, establece la comparación mayor o igual que. Se devolverá T si y sólo si cada valor es mayor o igual que el que le sucede, si no, nil. Las demás consideraciones son idénticas a las otras funciones similares explicadas. Ejemplos:

(>= 33 23 23 12 12 54) devuelve nil
(>= 24 24 24 23 23 0.01 –3)
devuelve T

 

3ª fase intermedia de ejercicios

· Indicar el resultado de AutoLISP (T o nil) ante las siguientes proposiciones:

(= 23 23.0)
(= 48.0 (* 6 8))
(= "AutoLISP" "autolisp" "aUtOlIsP")
(/= (/ 7 2) (/ 2 7))
(/= "libro" "libro ")
(< 3 5 6 (+ 5 –67))
(<= "A" "A" "bc" "zk" "zk")
(> "coche" "mesa")
(>= "coche" "cochecito")
(>= "cochu" "coche" "coche" "cocha")
(>= "á" "á" "a")


ONCE.4.4. Operaciones lógicas

Además de lo estudiado hasta ahora, existen cuatro operaciones lógicas referidas al álgebra de Boole. Estas operaciones son el Y lógico, el O lógico, la identidad y el NO lógico. Además, existe una quinta función que veremos al final denominada de identidad de expresiones y que es un poco especial.

Las cuatro funciones que vamos a ver actúan como operadores lógicos y devuelven, al igual que las anteriores, únicamente los resultados T (cierto) o nil (falso).

(AND expresión1 [expresión2...])


Esta función realiza el Y lógico de una serie de expresiones indicadas que representan otras tantas condiciones. Esto significa que evalúa todas las expresiones y devuelve
T si ninguna de ellas es nil. En el momento en que alguna es nil, abandona la evaluación de las demás y devuelve nil. Es decir, se deben cumplir todas y cada una de las condiciones. Veamos un ejemplo:

(AND (<= 10 10) (>= 10 10)) devuelve T

Esto significa que, si se cumple la condición de la primera lista (<= 10 10) y, además, se cumple la de la segunda lista (>= 10 10) devolverá T. Como esto es así, devuelve T.

De otra forma, si una de las condiciones no se cumple, devuelve nil, por ejemplo en el siguiente caso:

(AND (= 10 10) (> 10 10))

La primera condición en verdadera (10 es igual a 10), pero la segunda es falsa (10 no es mayor que 10). Como una ya no se cumple se devuelve nil. Han de cumplirse todas las condiciones para que sea el resultado verdadero. Veamos otros dos ejemplos:

(AND (= 10 10) (> 23 22.9) (/= "camión" "camioneta")) devuelve T
(AND (<= "A" "a") (= 5 7))
devuelve nil

No tiene mucho sentido indicar una sola expresión con esta función. Las dos siguientes son idénticas y producen el mismo resultado:

(AND (= 20 -20))
(= 20 -20)

Ambas devuelven nil.

(OR expresión1 [expresión2...])


Realiza un O lógico de una serie de expresiones que representan otras tantas condiciones. Evalúa las expresiones y devuelve
nil si todas ellas son nil. En el momento en que encuentre una respuesta distinta de nil, abandona la evaluación y devuelve T. Ésta es precisamente la mecánica del O lógico, es decir, basta que se cumpla una de las condiciones para que la respuesta sea verdadera o cierta.

El siguiente ejemplo compara números y devuelve nil:

(OR (< 20 2) (> 20 2))

O sea, si es menor 20 que 2 —que no lo es— o si es mayor 20 que dos —que sí lo es—, devuelve T. El cumplirse una de las dos condiciones es condición suficiente para que devuelva T. Veamos otro ejemplo:

(OR (= 20 2) (> 2 20)) devuelve nil

En este caso ninguna de las dos condiciones se cumplen (ambas son nil), así que el resultado final será nil.

Como en el caso de la función AND, no tiene sentido utilizar una sola expresión, ya que el resultado sería el mismo que al escribirla sola. Veamos otros ejemplos:

(OR (>= 30 30 20 –5) (<= -5 –5 –4 0)) devuelve T
(OR (< (* 2 8) (* 2 3)) (= (/ 8 2) (* 4 1)))
devuelve T
(OR (= "carro" "carreta") (= "casa" "caseta") (= 2 3)
devuelve nil

Recapitulando, y para afianzar estos dos últimos conocimientos, decir que AND obliga a que se cumplan todas las condiciones para devolver T. Sin embargo, a OR le basta con que una de ellas se cumpla para devolver T. Digamos, en lenguaje coloquial, que AND es "si se cumple esto, y esto, y esto, y... es válido", y OR es "si se cumple esto, o esto, o esto, o... es válido".

Veamos ahora otra función lógica para comparar expresiones. Se llama EQUAL y su sintaxis es la siguiente:

(EQUAL expresión1 expresión2 [aproximación])

Esta función compara las dos expresiones indicadas, si son idénticas devuelve T, si difieren en algo devuelve nil.

A primera vista puede parecer igual a la función = (igual que) estudiada, sin embargo, ésta únicamente comparaba valores; EQUAL tiene la capacidad de poder comparar cualquier expresión o lista de expresiones. De esta forma, podemos utilizar EQUAL de la misma forma que =, así:

(EQUAL 2 2) devuelve T
(EQUAL –3 5)
devuelve nil

Pero no tiene mucho sentido, ya que tenemos la función =. Reservaremos EQUAL para lo expuesto, es decir, para la comparación de listas de expresiones.

Así pues, y adelantándonos a algo que veremos un poco más tarde, diremos que la expresión de las coordenadas de un punto 3D se escribiría de la siguiente forma:

’(20 20 10)

El apóstrofo es la abreviatura de la función QUOTE de AutoLISP, que toma como literales, y sin evaluar, las expresiones que le siguen. De esta forma, para comparar la identidad de dos puntos haríamos, por ejemplo:

(EQUAL ’(20 20 10) ’(20 20 10)) devuelve T

(EQUAL ’(20 –5 10) ’(20 20 10)) devuelve nil

NOTA: La función QUOTE se ve ampliada en la sección ONCE.5.1.

El argumento optativo aproximación se utiliza cuando se comparan expresiones cuyos resultados son números reales y puede haber una pequeña diferencia decimal que no queramos considerar desigual. Con este argumento suministramos a la función un valor de aproximación decimal respecto al cual se creerán iguales los resultados. Por ejemplo:

(EQUAL 23.5147 23.5148) devuelve nil
(EQUAL 23.5147 23.5148 0.0001)
devuelve T

(NOT expresión)

La función NOT devuelve el NO lógico, es decir, si algo es verdadero devuelve falso y viceversa. Así, cuando el resultado sea distinto de nil (T), devolverá nil; cuando el resultado sea nil, devolverá T. Por ejemplo:

(NOT (= 2 2)) devuelve nil
(NOT (/= 2 2))
devuelve T

(EQ expresión1 expresión2)

Esta función no es propiamente lógica, sino que se denomina de identidad de expresiones. Aún así, la introducimos en este apartado por su similitud con las anteriores.

EQ compara las dos expresiones (sólo dos y ambas obligatorias) indicadas y devuelve T si ambas son idénticas o nil en caso contrario. Se utiliza sobre todo para comparar listas y ver si hay igualdad estructural.

La diferencia de EQ con EQUAL es que ésta última compara los resultados de evaluar las expresiones, mientras que EQ compara la identidad estructural de las expresiones sin evaluar. Por ejemplo, y adelantando la función SETQ que enseguida veremos, podemos hacer lo siguiente:

(SETQ list1 ’(x y z))
(SETQ list2 ’(x y z))
(SETQ list3 list2)
(EQ list1 list2)
devuelve T
(EQ list2 list3)
devuelve nil

Se observa que list1 y list2 son exactamente la misma lista por definición, están declaradas con SETQ y por separado, siendo sus elementos iguales. Pero list3 es, por definición, igual a list2 y no a list3, aunque sus elementos sean iguales. Es por ello que, en la segunda evaluación, EQ devuelve nil.

NOTA: Comprenderemos enseguida el funcionamiento y base de la función SETQ, no hay preocuparse.

 

4ª fase intermedia de ejercicios

· Indicar el resultado de AutoLISP (T o nil) ante las siguientes proposiciones:

(AND (= (* 20 20) (/ 800 2)) (> 300 200 500))
(AND (>= "a" "a") (>="z" "a") (>= " " " ") (>= "" ""))
(AND (OR (= 2 2) (> 3 6)) (OR (= 7 5) (= 0 0)))
(EQUAL (AND (= 1 10) (= 1 1)) (OR (>= 3 2 1 0) (<= 0 –2)))
(OR (AND (= 1 1) (= 2.0 2)) (OR (NOT (= 1 1)) (= 2.0 2)))

NOTA: Apréciese la capacidad de poder anidar y combinar expresiones.

Y hasta aquí llega esta parte de funciones matemáticas, lógicas y de comparación. Probablemente el lector estará pensando que de poco sirve lo expuesto hasta ahora: qué más dará que una expresión matemática me dé un resultado si luego no puedo operar con él; que importará que una proposición lógica me devuelva T o nil si no me sirve para otra cosa.

Paciencia... En el mundo de la programación hay que empezar desde abajo y, aseguramos que un buen dominio abstracto de lo visto hasta ahora proporcionará un gran nivel de soltura a la hora de programar de verdad. Seguramente, además, aquella persona que sepa programar en algún lenguaje existente, habrá comprendido algo más —ya que todos son muy parecidos—. El neófito comenzará a ver las cosas claras inmediatamente.

A partir de la siguiente sección comenzaremos a ver para qué sirve todo esto y cómo utilizarlo prácticamente en programas propios.

Autor: Jonathan Préstamo Rodríguez.
Para: La Web del Programador.