Sie sind auf Seite 1von 33

Inteligencia artificial

Algunos procedimientos
interconstruidos en el lenguaje
Keyword
¿Cómo diseñar un lenguaje?

Se tiene que tomar en cuenta tres


influencias principales:
• La computadora subyacente en donde
se van a ejecutar los programas
escritos en el lenguaje.
• El modelo de ejecución, o
computadora virtual, que apoya a ese
lenguaje en el equipo real.
• El modelo de computación que el
lenguaje implementa.
Componentes fundamentales de una computadora

Componente Descripción
Datos Son los elementos de información integrados a la computadora, manipulables
directamente a través de operaciones primitivas de hardware.
Operaciones primitivas Debe contener un conjunto de operaciones primitivas interconstruidas, útiles
para la manipulación de datos.
Control de secuencia Proporciona los mecanismos para controlar el orden en el que se van a
ejecutar las operaciones primitivas.
Acceso a datos Incorporar algún medio para designar operandos y un mecanismo para
recuperar operandos de un designador de operandos dado.
Gestión de almacenamiento Proveer mecanismos para la asignación de almacenamiento para programas.
Entorno de operación. El entorno de operación de una computadora consiste ordinariamente en un
conjunto de dispositivos periféricos de almacenamiento de entrada / salida
Máquina virtual

Son las estructuras de datos y algoritmos


de un lenguaje que se emplean durante el
tiempo de ejecución de un programa.
Relación entre lenguaje y máquina virtual

 Una máquina define un lenguaje.


 Un lenguaje define una máquina.
Jerarquía de máquinas virtuales

Una computadora con n niveles puede


verse como n máquinas virtuales
diferentes, cada una de las cuales tiene
un lenguaje especial.
Traductor para la máquina virtual

Se debe suministrar un traductor para


traducir programas de usuario al lenguaje
de la máquina de la computadora virtual
definida por el lenguaje.
Jerarquía de máquinas virtuales

 Cada nivel representa una abstracción con objetos y operaciones diferentes.


 Cada nivel está construido sobre su predecesor.
 Si se quiere escribir programas para la máquina virtual del nivel n, no se necesita
conocer los intérpretes ni los traductores de los niveles de abajo.

 Las computadoras están diseñadas como una serie de niveles.


 Para diseñar nuevos niveles, se necesita conocer todos.
Enlaces y tiempo de enlace

 Un enlace es la asignación de atributos


a una celda de memoria para un
elemento de programa.
 El momento en que el programa hace
esta elección se conoce como el
tiempo de enlace.
Tipos de tiempos de enlace

 Tiempo de ejecución  Tiempo de implantación del lenguaje


 El enlace de parámetros formales a reales.  Representación de números y operaciones
aritméticas en la computadora del
 A través de la asignación de valores a hardware subyacente.
variables.
 Tiempo de definición del lenguaje
 Tiempo de compilación  Todas las posibles formas opcionales de
 Tipos para las variables. enunciados, tipos de estructuras de datos,
 Cómo se guardan las estructuras de datos estructuras de programa.
y sus descriptores.
 Tiempo de carga  Por ejemplo, cuántos tipos de enlace tiene
este sencillo enunciado de asignación escrito
 Fusionar los subprogramas en un en un lenguaje L:
ejecutable único enlazando las variables a
direcciones reales de memoria.
X := X + 10
Tipos de tiempos de enlace

 Cuando un enlace se efectúa durante


el tiempo de ejecución, se dice que es
de tipo dinámico.
 Ejemplos: Prolog, LISP y ML.
Tipo Eficiencia Flexibilidad
Dinámico - +
 El enlace que ocurre durante el tiempo
de compilación es de tipo estático. Estático + -
 Ejemplos: C, Pascal y Fortran.
Alcance de una variable

 Es el conjunto de enunciados en el que el identificador de la variable es válido.

 Alcance estático: El alcance se determina de acuerdo al lugar donde el identificador


es definido. Se le llama también alcance lexicográfico.

 El alcance estático se determina fácilmente utilizando diagramas de contorno.


Paradigmas de los lenguajes de programación

En ciencias de la computación un 1. Lenguajes imperativos o de


paradigma se puede definir como un procedimientos.
conjunto de conceptos que permiten
modelar el mundo. 2. Lenguajes aplicativos o
funcionales.
Un paradigma es usado para formular una 3. Lenguajes con base en reglas o
solución de cómputo a un problema. lógicos.
4. Lenguajes orientados a objetos.
5. Lenguajes concurrentes.
1. Lenguajes imperativos o de procedimientos

Se caracterizan por ser claros,


formales y elegantes. Fortran
 Son controlados por enunciados
imperativos: INTEGER I
enunciado 1; REAL X(10), SUM
SUM = 0.0
enunciado 2; DO 100 I=1,10
... 100 SUM=SUM+ X(I)**2
IF (SUM .GT. 1E+5) STOP
WRITE(6,200) I,SUM
 La ejecución de un enunciado hace que el 200 FORMAT ('SUMA', I, 'VALORES E',E15.7)
intérprete cambie el valor de una o más END
localidades en memoria.
 Ejemplos: Fortran, Pascal, C, Algol, Ada,
PL/1.
2. Lenguajes aplicativos o funcionales

Se caracterizan por ser muy eficientes, expresivos y semánticamente elegantes.


 Los lenguajes aplicativos hacen uso de las funciones puras con composición funcional, recursión y
expresiones condicionales.
 Tienen 4 componentes:
• Un conjunto de funciones primitivas.
• Un conjunto de formas funcionales.
• La operación de aplicación.
• Un conjunto de objetos de datos.
 Ejemplos: LISP, ML. LIPS
; Factorial

(defun fact (n)


(if (= n 1) ; caso de terminación -> 1! = 1
1
(* n (fact (- n 1))) ; relación recursiva: n! = n * (n-1)!
)
)
3. Lenguajes con base en reglas o lógicos

Se caracterizan por ser eficaces y Prolog


veloces
 Se ejecutan verificando una condición, que
cuando se satisface ejecutan una acción:
condición 1 entonces acción 1
condición 2 entonces acción 2
...
 Ejemplo: Prolog.
4. Lenguajes orientados a objetos
Java
Se caracterizan por trabajar con entes
abstractos (objetos) que reflejan las class TestTh extends Thread {
private String nombre;
propiedades y características de private int retardo;
// Constructor para almacenar nuestro nombre
objetos o entes reales. // y el retardo
public TestTh( String s,int d ) {
 Las actividades a realizarse se tornan nombre = s;
retardo = d;
alrededor de los objetos mediante métodos }
// El metodo run() es similar al main(), pero para
(funciones). // threads. Cuando run() termina el thread muere
public void run() {
 La comunicación con el objeto se da a través // Retasamos la ejecución el tiempo especificado
try {
de mensajes. sleep( retardo );
} catch( InterruptedException e ) {
 Un aspecto fundamental es el concepto de ;
}
herencia que se da cuando los objetos // Ahora imprimimos el nombre
pertenecen a la misma clase. }
System.out.println( "Hola Mundo! "+nombre+" "+retardo );

 Ejemplos: Simula, Smalltalk, Java. }


5. Lenguajes concurrentes

Su principal objetivo es mejorar la Ada


velocidad de cómputo, compartir
recursos y distribuir la carga de
procedure DECOD_MENSAJE
trabajo. task GENERAR_CODIGOS;
 Diferentes tipos de arquitecturas: task DECODIFICAR is
– Redes de cobertura amplia. entry ENVIAR_CODIGO (C: in CHARACTER);
entry RECIBIR_CAR (C: out CHARACTER);
– Redes locales.
end;
– Multiprocesadores (Clusters). task IMPR_MENSAJES;
 Comunicación y cooperación entre task body GENERAR_CODIGOS is
aplicaciones a través de: CODIGO_SIGUIENTE: CHARACTER;
– Envío y recepción de mensajes. begin
loop
– Llamado a procedimiento remoto. --setencias para recibir datos
– Comunicación de grupo. --y generar un valor para CODIGO_SIGUIENTE
– Memoria Virtual Distribuida. DECODIFICAR.ENVIAR_CODIGO (CODIGO_SIGUIENTE);
end;
 Ejemplos: PVM, CSP, Ada.
var(X)
Determinación del tipo de un término
Se satisface si en ese momento X es una variable no
instanciada
Permite saber si una variable ya tiene o no un valor, nonvar(X)
pero sin fijárselo como efecto lateral Comportamiento opuesto al anterior
?- var(X).
yes atom(X)
?- var(23). Se cumple si X identifica en ese momento un átomo
no ?- atom(23).
?- X = Y, Y = 23, var(X). no
¿? ?- atom(libros).
listing(A). yes
Se muestran por el canal de salida activo todas las cláusulas ?- atom(“esto es una cadena”).
asociadas al átomo al que esté instanciado A. ¿?
El formato depende del intérprete.
Útil para descubrir errores.
integer(X)
Ejemplo:
Se satisface si X representa en ese momento a un entero
?- [recorrer_fichero].
?- listing(mostrar_fichero).
atomic(X)
mostrar_fichero :-
Se cumple si en ese momento X es un entero o un
write('Nombre de fichero: '),
átomo
read(A),
atomic(X):- atom(X).
see(A),
muestra_contenido, atomic(X):- integer(X).
seen.Manejo de cláusulas
Functor

Una función entre categorías que


mapea objetos a los objetos
y morfismos a morfismos. Existen
Functors en ambos tipos
covariantes y contravariantes.
Name

name(A, L) Ejemplos:
• Permite manejar átomos ?- name(prueba, X).
arbitrarios. X = [112, 114, 117, 101, 98, 97]
• Relaciona un átomo (A), con la ?- name(prueba, “prueba”).
lista de caracteres ASCII que lo yes
compone (L).
?- name(X, [112, 114, 117, 101, 98,
97]).
X = prueba
Manipulación de la base de datos

Programa Prolog <----> Base de datos

Base de datos: Conjunto de cláusulas


que hemos ensamblado antes de
iniciar la ejecución del programa.

Prolog dispone de un conjunto de


predicados predefinidos para
modificar la base de datos de forma
dinámica.
Predicados para manipulación de la base
de datos
Predicados Descripción
asserta(X) Añade la cláusula X como la primera cláusula de este predicado.
Como otros predicados de E/S siempre falla en el backtracking y no deshace sus
propios cambios.
assertz(X) Como asserta/1, sólo que añade la cláusula X como la última cláusula del
predicado.
retract(X) Borra la cláusula X de la base de datos.
Como en los casos anteriores no es posible deshacer los cambios, debido a este
predicado en el backtraking.
retract/assert: Modificar la base de datos de cláusulas.
Compilan el término que se les pasa como argumento.
Son costosas.
recorda/erase: Permiten grabar/borrar una base de datos de términos.
Mecanismo más rápido que assert/retract, pero no son cláusulas del programa.
Construcción y descomposición de términos

Existen tres predicados • ?- f(a,b) =.. L.


predefinidos para descomponer • L = [f, a, b]
términos o construir nuevos
términos: • ?- T =.. [progenitor, miguel, maría ]
• T = progenitor(miguel, maría)
Term =.. L
• ?- Z =.. [p, X, g(X,Y) ].
functor(Term, F, N) • Z = p(X, g(X,Y))

arg(N, Term, A)
Prolog VI 25
Los procedimientos Findall

findall(Instance, Goal, List)

List se unifica con la lista de todas


las instancias de Instance que
hacen cierto a Goal.
Si Goal no es cierto para ningún
valor de Instance, entonces List se
unifica con la lista vacía [].
Predicados standard de orden superior

• map • Ejemplo
Permite aplicar un predicado de "mapeo" a una %Predicado de mapeo:
lista de datos. Dicho predicado debe admitir el
siguiente modo de uso: %Dado un numero le suma una
unidad
MapPred(+Dato,-DatoMapeado).
mapeo(Dato, DatoMapeado) :-
Debe tratarse, por tanto, de un predicado que DatoMapeado is Dato + 1.
transforma (mapea) un dato en otro. La función de
map es la siguiente: para cada dato existente en %% Ejecucion en el top-level:
una lista dada, se pasa como primer argumento a ?- map([6,9,12],mapeo,L).
MapPred. El resultado de MapPred, es decir, el
segundo argumento, se almacena en una lista L = [7,10,13] ?
resultado. El modo de uso es el siguiente:
yes
map(+ListaInicial, +MapPred, -ListaResultado). ?-
Predicados estándar de orden superior
• "findall" Genera una lista con todas las soluciones
del predicado dado según el orden en que
Se trata de un conjunto de predicados se van sucediendo. findall nunca falla, si
cuya finalidad es almacenar en una lista no hay soluciones genera una lista vacía.
todas las soluciones de un predicado Naturalmente, el propio findall/3
dado, entendiendo como tales, las solamente tiene una solución.
ligaduras que se producen en una o varias
variables libres que se indican
explícitamente. Los predicados que
componen la familia son:

• El modo de uso es el siguiente:


• findall(+Termino_o_variable,
+Objetivo, -ListaResultado).
Uso de findall
• uso erróneo • usos correctos
• findall( X, predicado(Y), • findall( X, predicado(X),
Resultado). Resultado).
• findall( X, predicado(Y,Z), • findall( X, predicado(X,Y),
Resultado). Resultado).
• findall( solucion(X,Y), • findall( solucion(X,Y),
predicado(Y,Z), Resultado). predicado(X,Y), Resultado).
Uso de findall
• uso erróneo • usos correctos
• findall( X, predicado(Y), • findall( X, predicado(X),
Resultado). Resultado).
• findall( X, predicado(Y,Z), • findall( X, predicado(X,Y),
Resultado). Resultado).
• findall( solucion(X,Y), • findall( solucion(X,Y),
predicado(Y,Z), Resultado). predicado(X,Y), Resultado).
Los procedimientos Bagof

bagof(Instance, Goal, List)

Similar a Findall, excepto en cómo


trata las variables que aparecen en
Goal y no en Instance (conocidas
como variables libres). Bagof hace
backtracking y produce una lista List
para cada posible ligadura de las
variables libres. Se puede convertir
una variable libre a no-libre usando ^ .
Si Goal no es cierto para ningún valor
de Instance, entonces List se unifica
con la lista vacía [].
Los procedimientos Setof

setof(Instance, Goal, List)

Similar a Bagof, salvo en que List


está ordenada (según el orden
estándar) y sin repetidos.
“La primera regla de cualquier tecnología utilizada en los negocios es que
la automatización aplicada a una operación eficiente magnificará la
eficiencia. La segunda es que si la automatización se aplica a una
operación ineficiente, magnificará la ineficiencia”

Bill Gates

Das könnte Ihnen auch gefallen