domingo, 7 de noviembre de 2010

LENGUAJES IMPERATIVOS - Generalidades ALGOL

Laboratorio de Lenguajes de Programación - Semana 8

Su nombre proviene del acrónimo ALGOrithmic Languaje (Lenguaje Algoritmico), se desarrollo en la década de los años 60 y se convirtió en el estándar para el diseño de algoritmos en libros por los siguientes 30 anos, sin embargo, a pesar de su uso nunca llego a sobresalir como lenguaje de uso comercial, su uso quedo aislado solamente a investigaciones cientificas.

Un comité de representantes de Europa y América diseñaron ALGOL en 1958, en una respuesta a la creciente necesidad de tener un solo lenguaje de programación que fuese universal e independiente de la arquitectura de las computadoras de la época.

Los tres objetivos que rigieron el desarrollo de Algol fueron:

1) Debía ser tan cercano como fuese posible a la notación matemática estándar y debía ser legible dando pocas explicaciones adicionales.

2) Debía ser posible usarlo para la descripción de procesos de cómputo en las publicaciones científicas.

3) Debía ser traducible, de manera mecánica, a programas en lenguaje máquina.

Para sorpresa de todos el diseño original de ALGOL tomó sólo 8 días (el lenguaje consistía de unos cuantos constructores de propósito general y no de una cantidad innumerable de funciones barrocas). Asi, Algol 60 (la primera revision de Algol 58) estaba lista para mayo de 1960.

Algol influyó a muchos lenguajes de la época, por lo que nos daremos cuenta que mucha de la sintaxis de otros lenguajes old school es parecida a la de Algol.

La version que analizaremos sera Algol66.

INSTALANDO EL COMPILADOR

Algol forma parte de la familia de lenguajes imperativos, y un código fuente escrito en Algol necesita ser compilado (aunque parecera mas que lo estaremos interpretando), asi que lo primero es instalar y configurar el compilador.

Lo primero que vamos a hacer es visitar esta pagina y descargar el compilador a una carpeta en nuestro equipo (la descarga debe iniciar automaticamente)

Algol 68 Compiler, Interpreter & Runtime

Nos vamos a dirigir a la carpeta donde descargamos el compilador y extraemos el contenido del archivo algol68g-2.0.0.tgz, lo que nos generará una carpeta llamada algol68g-2.0.0.

Ahora, vamos a abrir nuestra terminal y nos vamos encaminamos a la carpeta algol68g-2.0.0, dentro de la carpeta vamos a encontrar un archivo llamado configure


Para ejecutarlo tecleamos la secuencia ./configure.

Una vez que termine tecleamos la secuencia: make

Veremos una lista de archivos con extensión *.c que estan siendo compilados.


Y despues tecleamos la secuencia make install


Para el correcto funcionamiento del compilador necesitamos instalar la libreria libncurses5-dev con la secuencia:

sudo apt-get install libncurses5-dev


(en mi caso ya la tengo instalada puesto que la necesite en el compilador de Cobol, sin embargo ustedes prosigan con su instalacion, aceptando los mensajes de confirmacion)

Por ultimo una vez mas la secuencia make y despues make install

Con ello ya tenemos listo el compilador, la terminacion del codigo fuente en Algol es *.a68

VARIABLES Y DATOS

Al igual que en muchos lenguajes de programacion, Algol maneja tipos simples de datos y otros mas complejos, estan por ejempo:

INT: Enteros
REAL: Numeros punto flotante
DOUBLE: Punto flotante de precision doble
CHAR: Caractéres
BOOL: Lógicos o Booleanos
COMPLEX: Complejos
STRING: Cadenas de caractéres.
NODE: Nodos (para grafos, árboles, ect)
FILE: Manejo de archivos

En Algol a estos tipos de datos de les conoce como mode-indicants (indicadores de modo), en otros lenguajes de les llama type identifier (identificadores de tipo [de dato]).
Los indicadores de dato se pueden complementar con el indentificador de modo LONG




Las variables se declaran con la siguiente sintaxis:

[mode-identifier] [var name]

Por ejemplo:

INT numero
CHAR letra
STRING nombre

Para declarar una variable e inicializarla se sigue esta sintaxis:

[mode-identifier] [var name] := [value]

Por ejemplo:

REAL pi := 3.14159;
CHAR letra := "A";
STRING nombre := "Juan Carlos";

ENTRADA Y SALIDA DE DATOS

Para mostrar los datos en pantalla (salida), se utiliza la funcion print();, lo que se va a imprimir se escribe dentro de doble parentesis y encerrado en comillas dobles, por ejemplo:

print (("Hola, mundo"));

Si se quiere pasar un espacio se escribe new line dentro de los parentesis, por ejemplo:

print (("Hola, mundo", new line));

Para tomar datos desde el teclado se utiliza el proceso read;, se sigue la siguiente sintaxis:

[mode-identifier] [var name] = read [mode-identifier [low-case]];

Por ejemplo:

INT x = read int;

FUNCIONES MATEMATICAS

Algol incluye algunas funciones que nos pueden ser muy utiles al momento de escribir nuestro codigo; aqui se muestran algunas:

sqrt(x): Raiz Cuadrada
curt(x): Raiz Cúbica
exp(x): Potencias
ln(x): Logaritmo Natural
log(x): Logaritmo base 10
sin(x): Seno
arcsin(x): Seno Inverso
cos(x): Coseno
arccos(x): Coseno Inverso
tan(x): Tangente

ESTRUCTURA DEL CÓDIGO

Todo código en Algol tiene que estar delimitado por clausulas que marquen su inicio y su final de esta forma:
BEGIN
  ...
  PROCEDURES
  ...
END


Con ello podemos definir el código mas corto que podemos escribir :)
BEGIN
  print(("HOLA MUNDO", new line));
END


Los comentarios se limitan mediante la etiqueta COMMENT:
BEGIN
  COMMENT
     Este es mi primer programa en Algol
  COMMENT
  print(("HOLA MUNDO", new line))
END


SECUENCIAS DE CONTROL

Condicional
BEGIN
   IF INT x = read int;
      x < 0
   THEN print ((x, " es negativo"))
   ELSE print ((x, " no es negativo"))
   FI
END


CICLOS
BEGIN
  INT j := 10;
  FOR i TO j DO
     print (("HOLA", new line))
  OD
END


Desde un valor a otro final, incremento
BEGIN
  FOR i FROM -10 TO 10 DO
     print ((i, new line))
  OD
END


Desde un valor a otro final, dos en dos
BEGIN
  FOR i FROM 0 BY 2 TO 10 DO
     print ((i, new line))
  OD
END


Desde un valor a otro final, decremento
BEGIN
  FOR i FROM 10 DOWNTO 1 DO
     print ((i, new line))
  OD
END


CICLO WHILE
BEGIN
  INT x;
  WHILE
     read(X);
     int > 0
  DO
     print (("Mas abajo..."))
  OD
END


EJEMPLO

Ahora que ya vimos la teoria, vamos a la práctica; escribamos un pequeño código en Algol que nos calcule potencias.

Abrimos una terminal y tecleamos emacs -nw potencia.a68

Despues escribimos este código:
BEGIN
  INT base;
  INT exp;
  LONG INT pot := 1;

  print(("BASE: "));  
  read(base);
  print(("EXPONENTE: "));  
  read(exp);

  FOR i TO exp DO
     pot := pot * base
  OD;

  print((base," elevado a la potencia",exp," es",pot))
END


Para compilarlo necesitamos regresar a la carpeta donde esta el compilador algol68g-2.0.0, esto lo hacemos desde la terminal claro esta.
Ya que estamos en la carpeta algol68g-2.0.0 tecleamos esta sintaxis para ejecutarlo:

./a68g /ubicacion_codigo_fuente/, en mi caso:

./a68g /home/juancarlos/temp/potencia.a68


Espero que les haya servido esta información, en la barra de recursos les deje un tutorial para Algol bastante bueno: Tutorial ALGOL.

SALUDOS!! ^_^

LENGUAJES IMPERATIVOS - Generalidades PASCAL

Laboratorio de Lenguajes de Programación - Semana 8

Pascal es un lenguaje de programación desarrollado por el profesor suizo Niklaus Wirth entre los años 1968/9 y publicado en 1970. Su objetivo era crear un lenguaje que facilitara el aprendizaje de programación a sus alumnos, utilizando la programación estructurada y estructuración de datos. Sin embargo con el tiempo su utilización excedió el ámbito académico para convertirse en una herramienta para la creación de aplicaciones de todo tipo.

Pascal se caracteriza por ser un lenguaje de programación estructurado fuertemente tipificado. Esto implica que:

1. El código está dividido en porciones fácilmente legibles llamadas funciones o procedimientos. De esta forma Pascal facilita la utilización de la programación estructurada en oposición al antiguo estilo de programación monolítica.
2. El tipo de dato de todas las variables debe ser declarado previamente para que su uso quede habilitado.

El nombre de Pascal fue escogido en honor al matemático Blaise Pascal.

A diferencia de lenguajes de programación descendientes de C, Pascal utiliza el símbolo ":=" para la asignación en vez de "=". Si bien el segundo es más conocido, la práctica ha demostrado que muchos usuarios utilizan el símbolo de igualdad para comparar valores en lugar del comparador de C que es el símbolo ==. Esta sintaxis conduce a muchos errores o bugs difíciles de rastrear en código C. Dado que Pascal no permite asignaciones dentro de expresiones y utiliza sintaxis distintas para asignaciones y comparaciones, no sufre estos errores.

FUENTE: http://es.wikipedia.org/wiki/Pascal_%28lenguaje_de_programaci%C3%B3n%29


COMPILADOR

Pascal necesita un compilador para generar ejecutables útiles, asi que lo primero que vamos a hacer es instalarlo.
Primero abrimos nuestra terminal, para escribir la siguiente orden:

sudo apt-get install fp-compiler


Nos aparecera en la terminal un mensaje de confirmación, aceptamos y dejamos que prosiga la instalación.

Una vez terminados todos los procesos podemos teclear fpc para llamar al compilador, nos saldrán varias pantallas con información del compilador (dando varias veces ENTER salimos).
La extension de los archivos fuente escritos en Pascal es *.pas


VARIABLES Y DATOS

La asignación de unidades de memoria para el ejecución del programa se realiza con la declaración de variables, las cuales pueden ser lógicas, numericas, cadenas de caractéres.


la declaración de variables se hace con esta sintaxis:
var
   nom_var: type;


para inicializarlas se hace en el siguiente bloque con la sintaxis:
begin
   nom_var := value;


por ejemplo:
var
   i: Integer;
   s: String;
   b: Boolean;
 
begin
   i := -3;
   s := 'Hello';
   b := True;


Podemos realizar varias operaciones aritméticas con las variables declaradas:



por ejemplo en el siguiente programita:
program Ejemplo;
 
var
   X, Y, S, R, M, D: Integer;
 
begin
   X := 5;
   Y := 10
   S := X + Y;
   R := Y - X;
   M := X * Y;
   D := Y / X;
end.

(se que falta imprimir resultados, es solo ejemplo)

Las constantes de declaran con la siguiente sintaxis, dentro de su propio bloque de datos:
const
   nom_const: Type = value;


Por ejemplo:
const
   pi: Real = 3.14;


ENTRADA Y SALIDA DE DATOS

Para leer datos desde el teclado se utilizan las funciones Readln y ReadKey, ReadKey lee un solo caractér, mientras que Readln lee numeros y cadenas de caractéres, ambos funcionan de distinta forma:
program Ejemplo2;
 
uses crt;
 
var
   i: Integer;
   s: String;
   c: Char;
 
begin
   Readln(i);
   Readln(s);
   c := ReadKey;
end.


Para imprimir mensajes en pantalla o los resultados de una operación se utilizan la funciones Writeln() y Write() , lo que se imprime va dentro del paréntesis, y cada dato se separa por comas, por ejemplo:
program Ejemplo3;
 
var
   i: Integer;
   s: String;
begin
   i := 24;
   s := 'Hello';
   Writeln(i);
   Writeln(s,' world');
end. 


SECUENCIAS DE CONTROL



CICLO IF... ELSE
program Si o no;
 
var
   i: Integer;
 
begin
   Writeln('Dame un valor');
   Readln(i);
   if i > 5 then
      Writeln('Mayor que 5')
   else
      Writeln('Menor que 5');
end. 


DECISIONES "CASE"
program Decisiones;
 
uses
   crt;
 
var
   Choice: Char;
 
begin
   Writeln('Elige la que mas te gusta');
   Writeln('a - Manzana:');
   Writeln('b - Platano:');
   Writeln('c - Zanahoria:');
   Choice := ReadKey;
   case Choice of
      'a': Writeln('Te gustan las manzanas');
      'b': Writeln('Te gustan los platanos');
      'c': Writeln('Te gustan las zanahorias');
   else
      Writeln('No te gusta nada de aqui');
   end;
end. 

CICLO FOR
program ciclo;
 
var
   i: Integer;
 
begin
   for i := 1 to 10 do
      Writeln('Hola, otra vez!!!');
end. 

CICLO WHILE
program Ciclos2;
 
var
   i: Integer;
 
begin
   i := 0;
   while i <= 10
      begin
         i := i + 1;
         Writeln('Hola, una vez mas.');
      end;
end. 

CICLO WHILE... UNTIL...
program Ciclos3;
 
var
   i: Integer;
   s: String;
 
begin
   i := 0;
   repeat
      i := i + 1;
      Write('Dame un valor: ');
      Readln(s);
   until (i = 10) or (s = 0);
end. 


EJEMPLO

Para terminar, teclearemos un ejemplo donde les mostrare la sintaxis de Pascal y practicaremos lo aprendido.
Un programa que me calcule el área de diversas figuras geometricas.
Abirmos la terminal y tecleamos:

emacs -nw areas.pas

Acto seguido, tecleamos el siguiente codigo:
program areas;

uses
   crt;

const
   pi: Real = 3.14159;
 
var
   Choice     : Char;
   X, Y, Area : Real;
   
begin
   Area := 0;
   Writeln('Calcular el area de: ');
   Writeln('a - Cuadrado');
   Writeln('b - Circulo');
   Writeln('c - Triangulo');
   Choice := ReadKey;
   case Choice of
     'a' : begin
         Writeln('Dame la longitud del lado');
         Readln(X);
         Area := X*X;
         Writeln('El area del cuadrado es: ', Area);
     end;   
     'b' : begin
         Writeln('Dame la longitud del radio');
         Readln(X);
         Area := pi*X*X;
         Writeln('El area del circulo es: ', Area);
     end;
     'c' : begin
         Writeln('Dame la longitud de la base');
         Readln(X);
         Writeln('Dame la altura: ');
         Readln(Y);
         Area := (X * Y) / 2;
         Writeln('El area del triangulo es: ', Area);
     end;
   end; { case }
end.

Despues que lo escribimos, lo guardamos y lo compilamos con la orden:

fpc areas.pas

Se generarán 2 archivos, un archivo objeto *.o y un ejecutable sin extensión "areas", para correrlo tecleamos: ./areas


Espero les haya gustado la entrada, en la seccion Recursos les deje el tutorial correspondiente a este lenguaje, donde ademas podran aprender como declarar arreglos, estructuras, punteros, etc.

SALUDOS!!! ^_^

LENGUAJES IMPERATIVOS - Generalidades BASIC

Laboratorio de Lenguajes de Programación - Semana 8

BASIC es el acrónimo de Beginners All-purpose Symbolic Instruction Code ("Código de instrucciones simbólicas de propósito general para principiantes")

"Forma parte de la familia de lenguajes de alto nivel. Originalmente fue desarrollado como una herramienta de enseñanza; se diseminó entre las microcomputadoras hogareñas a partir de la década de 1980. Actualmente continúa siendo muy popular, en muchos dialectos bastante distintos del original.
FUENTE: http://es.wikipedia.org/wiki/BASIC

Se dice que es un lenguaje hecho para niños, que ya esta en desuso, pero la verdad es de los pocos lenguajes "old school" que siguen vigentes para su uso.

BASIC fue diseñado para permitir a los estudiantes escribir programas usando terminales de un computador en tiempo compartido. Estaba pensado para reducir notablemente la complejidad de los otros lenguajes del momento, diseñado específicamente para un usuario más sencillo fuera del área de las ciencias de la computación y a quien no le interesaba tanto la velocidad, sólo el hecho de ser capaz de programar y usar la máquina sin demasiadas complicaciones. Los diseñadores del lenguaje también querían que permaneciera en el dominio público, lo cual contribuyó a que se diseminara rápidamente.

Los ocho principios que rigeron el diseño de BASIC fueron:

1. Ser fácil de usar para los principiantes.
2. Ser un lenguaje de propósito general (no orientado).
3. Permitir a los expertos añadir características avanzadas, conservando simple el lenguaje para los principiantes.
4. Ser interactivo.
5. Proveer mensajes de error claros y amigables.
6. Responder rápido en los programas pequeños.
7. No requerir un conocimiento del hardware de la computadora.
8. Proteger al usuario del sistema operativo.

INSTRUCCIONES INICIALES

Una vez mas estamos hablando de un lenguaje de programacion que requiere un compilador para generar sus archivos ejecutables.
Lo primero que vamos a hacer es entrar a esta pagina web:

FreeBasic Compiler

La descarga comenzara automaticamente. Cuando termine la descarga procedemos a descomprimir el contenido, se generara una carpeta llamada FreeBASIC-0.21.1-linux-standalone.

Despues abrimos nuestra terminal, y desde ahi nos dirigimos al lugar donde guardamos la carpeta, una vez detro de la carpeta (utilizando la terminal), ejecutaremos la siguiente secuencia:

sudo ./install-standalone.sh -i

Una vez que termine todo el proceso (no se nos preguntara nada), teclearemos en la terminal: fbc para llamar al compilador, si todo corrio bien veremos una ventana como esta:


Donde se listaran todos los atributos que se pueden agregar al compilar un codigo basic.
La extension de los archivos es *.bas

VARIABLES Y DATOS

Al igual que todos los lenguajes de programacion, BASIC se basa en la declaración de variables para la asignación de memoria.'
Las variables pueden ser numericas o cadena de caractéres.
La sintaxis de la declaración es:

DIM nombre_var AS tipo_var

Por ejemplo:

DIM numero AS INTEGER: crea la variable numero, de tipo número entero
DIM frase AS STRING: crea la variable frase, de tipo cadena
DIM a AS SINGLE: crea una variable a de tipo punto flotante
DIM b AS DOUBLE: crea una variable a de tipo punto flotante de precision doble

Estas declaraciones son equivalentes:

DIM numero%: crea la variable numero, de tipo número entero
DIM frase$: crea la variable frase, de tipo cadena
DIM a!, b#: crea dos variables a y b, de tipo número de precisión simple y doble, respectivamente.

$ - String - 8bits
% - Integer - 16bits
& - Long - 32bits
! - Single - 32bits
# - Double - 64bits

La palabra LET se usa para asignar un valor a una variable, actualmente esta en desuso para que el codigo se vea mas limpio, su sintaxis es:

LET nombre_var[type] = valor

Por ejemplo:

OLD SCHOOL: LET numero% = 523
NEW: numero% = 653

Si se intenta poner un valor decimal en una variable entera el valor se redondea. Se pueden poner valores enteros en variables Single y Double.

Cuando se quiere que la variable sea global, el nombre va precedido por la palabra SHARED

Por ejemplo:

DIM SHARED numero AS INTEGER
DIM SHARED cadena$

BASIC no es sensible mayósculas y minósculas, por lo que utilizar una variable hola
es igual a otra llamada Hola y tambien a otra llamada HoLa

Los compiladores tienen sus palabras reservadas las cuales no pueden ser utilizadas como nombres de variables y/o funciones, tales como DIM, END, PRINT, INTEGER, etc.

ESTRUCTURA DEL CODIGO

La programacion en BASIC se puede estructurar en funciones y subprogramas que ayudan a mejorar la legibilidad del mismo, por lo general siguen la siguiente estructura:
' Programa principal

 declaración de funciones y subprogramas
 declaración de variables
 sentencias

END

SUB Subprograma1 ( )

 declaración de variables
 sentencias

END SUB

FUNCTION Funcion1 ( )

 declaración de variables
 sentencias

END FUNCTION

...
...
...

SUB Subprograman( )

 declaración de variables
 sentencias
END SUB

FUNCTION Funcionn ( )

 declaración de variables
 sentencias

END FUNCTION


ENTRADA Y SALDA

Cuando se quiere imprimir algo en pantalla se utiliza la palabra PRINT, por ejemplo:

PRINT "HOLA"
PRINT "El valor de a es"; a%

Para leer un dato desde el teclado se utiliza la palabra INPUT, por ejemplo:

PRINT "Dame un numero: "
INPUT numero%

PRINT "Introduce tres valores: "
INPUT x%, y%, z%

Algo mas sencillo:

INPUT "Dame un numero: ", num%

Cadenas de texto:

DIM cadena AS STRING
INPUT 'Escribe unas palabras: ', cadena

EJEMPLO

Llego el momento de poner en práctica lo que hemos aprendido, vamos a teclear un pequeño código en BASIC.
Escribiremos un programa que nos convierta de grados centigrados a grados fahrenheit.
Abrimos nuestra terminal y tecleamos lo siguiente:

emacs -nw convierte.bas

Y escribimos el siguiente codigo en el editor EMACS (emacs no incluye Basic Mode):
'' Convierte Centigrados a Fahrenheit
  DIM cent AS SINGLE
  DIM fahr AS SINGLE

  PRINT "Dame los grados Centigrados: "
  INPUT cent
 
  fahr = cent * (9 / 5) + 32

  PRINT " ";cent;"C son";fahr;" F"

END


Una vez que terminemos, lo guardamos y lo compilamos con la siguiente orden:

fbc convierte.bas

Se generará un ejecutable sin extensión llamado convierte, para ejecutarlo escribimos: ./convierte



En la barra de "RECURSOS" les dejo un tutorial que me sirvio mucho para comprender este lenguaje: Tutorial BASIC"

Espero les haya gustado la entrada, dudas o sugerencias ya saben, comenten.

SALUDOS!!! ^_^

LENGUAJES IMPERATIVOS - Generalidades C

Laboratorio de Lenguajes de Programación - Semana 8

Todos conocemos a este lenguaje, considerado el mas importante hasta la fecha y quien a influenciado a una gran cantidad de lenguajes de programación.

A pesar de que es viejo, es muy apreciado por su la eficiencia del código que produce.
Se trata de un lenguaje débilmente tipificado de medio nivel pero con muchas características de bajo nivel. Dispone de las estructuras típicas de los lenguajes de alto nivel pero, a su vez, dispone de construcciones del lenguaje que permiten un control a muy bajo nivel. Los compiladores suelen ofrecer extensiones al lenguaje que posibilitan mezclar código en ensamblador con código C o acceder directamente a memoria o dispositivos periféricos.

Podemos mencionar entre sus principales caracteristicas:

* Un núcleo del lenguaje simple, con funcionalidades añadidas importantes, como funciones matemáticas y de manejo de archivos, proporcionadas por bibliotecas.
* Es un lenguaje muy flexible que permite programar con múltiples estilos. Uno de los más empleados es el estructurado "no llevado al extremo" (permitiendo ciertas licencias de ruptura).
* Un sistema de tipos que impide operaciones sin sentido.
* Usa un lenguaje de preprocesado, el preprocesador de C, para tareas como definir macros e incluir múltiples archivos de código fuente.
* Acceso a memoria de bajo nivel mediante el uso de punteros.
* Interrupciones al procesador con uniones.
* Un conjunto reducido de palabras clave.
* Por defecto, el paso de parámetros a una función se realiza por valor. El paso por referencia se consigue pasando explícitamente a las funciones las direcciones de memoria de dichos parámetros.
* Punteros a funciones y variables estáticas, que permiten una forma rudimentaria de encapsulado y polimorfismo.
* Tipos de datos agregados (struct) que permiten que datos relacionados (como un empleado, que tiene un id, un nombre y un salario) se combinen y se manipulen como un todo (en una única variable "empleado").

Con base a el han surgido otros lenguajes como C++, C#, Objective-C; que se consideran extensiones del mismo para proporcionarle programacion orientada a objetos.

PREPARACIÓN

El sistema operativo UBUNTU incluye el compilador de este lenguaje, su nombre es gcc, para verficar la existencia de este compilador podemos teclear en la terminal

gcc: lo que mostrara un mensaje como este, es una respuesta de la llamada que ejecutamos al compilador, lo que indica que esta instalado y preparado.



LO BÁSICO

En C, las variables se declaran de una forma clara y directa, algunas de ellas pueden ser de los tipos:

char: Caractér del ANSI C
int: Entero
float: Número con punto flotante
double: Número con precisión doble
bool: Lógico

Para su declaración se tiene la siguiente sintaxis:

TipoVariable nombre1, nombre2, ..., nombreN;

Por ejemplo:

char nombre;
int suma;
float pi;
double euler;

Existen también palabras reservadas que no podemos utilizar al momento de escribir nuestro código tales como if, for, while, do, else, break, main, void, return, etc.

Las variables pueden ser locales, y declararse dentro de la función donde vayan a ser utilizadas, con ello solo estaran disponibles para un solo proceso; sin embargo, tambien pueden ser globales y declararse fuera de una funcion, mas especificamente despues de declarar las librerias que han de anclarse al codigo.

ESTRUCTURA DEL CODIGO

Para estructurar un codigo en C, se sigue el siguiente esqueleto:
#include <stdio.h>
#include <libreria.h>
...
#define CONSTANTE
...

tipo variable global;

tipo funcion1 (tipo variable1, tipo variable2) {
  ...;
  procesos;
  ...;
  return;
}

tipo funcionn (...) {
 ...;
}

int main (int argc, char *argv[]) {
  ...;
  procesos;
  ...;
  return 0;
}


Esto es muy general, y algunas parte pueden omitirse o ampliarse dependiendo de la extensión de nuestro programa.

La funcion siempre lleva su tipo, su nombre y entre parentesis los argumentos que recibirá, posteriormente el alcance de la función se limita a un par de corchetes dentro de ellos va el proceso de la función, varias funciones pueden unirse y llamarse entre si para aumentar sus capacidades, el programa siempre terminará cuando se llegue al return 0 de la funcion main.

CICLOS

Son llamados tambien Secuencias de Control, un buen programa debe combinarlas de manera eficiente para lograr un objetivo, nos ayudan a:

- Ejecutar varias veces una secuencia de instrucciones
- Repetir una instruccion.
- Decidir entre alternativas.

Un ciclo if nos ayuda a evaluar una condición y alternar entre dos caminos o mas a seguir:


Su forma general:
...
if(expresion) {
  enunciado1;
} else {
  enunciado2
}
...

Cuando la expresión dentro del parentesis es evaluada como verdadera el enunciado 1 se ejecutara; se der falsa se procedera con la ejecucion del enunciado 2.

Un ciclo for nos sirve para repetir un bloque n cantidad de veces hasta alcanzar un limite determinado, hasta obtener un objetivo, encontrar un resultado, etc.


Es de la forma general:
...
for(expresion1; expresion2; expresion3) {
  ...
  proceso
  ...
}

En la expresion1 se declara el inicio del ciclo, en la expresion2 el limite a alcanzar, la expresion3 marcara si la expresion1 aumenta o disminuye su valor en n cantidad de pasos; mientras de alcanza el limite de la expresion3 el proceso se repetira.

Un ciclo while nos ayuda a evaluar un dato, y mientras ese dato no corresponda con la condicion predeclarada, el ciclo se repetira indefinidamente.


Es de la forma general:
...
while (condicion) {
  ...
  proceso
  ...
}
...

Son utilizadas paa generar pequenas pausas en el sistema, mientras se espera que el usuario proporcione determinada respuesta, tambien puede adaptarse y usarse indistintamente a un ciclo for.

Una sentencia switch nos ayuda a disernir entre varios caminos a seguir, a cada camino le corresponde un proceso completamente individual.


Son de la forma general:
...
switch(expresion entera) {
  case constante1:
      ...
      proceso1
      ...
  case constante2:
      ...
      proceso2
      ...
  case constanten:
      ...
      proceson
      ...
  default :
      ...
      predeterminado
      ...
}
...


Nos ayuda mas que nada a minimizar el uso de sentencias if... else... if lo que es un beneficio al momento de escribir codigos largos.

Dentro se las secuencias se pueden agregar las palabras reservadas continue y break

continue: causa que el resto de una iteración sea saltada y se prosiga con la ejecución de la siguiente.
break: causa la salida del ciclo para comenzar con la siguiente parte del programa.

EJEMPLOS

Para darle mas alcance a esta entrada, y suponiendo que ya todos entendemos lo basico de C, les voy a mostrar como funcionan los punteros en C.

Un puntero, valga la redundancia, apunta a otro dato de su mismo tipo y su valor es la direccion de memoria de la otra variable. Hay que recalcar que una direccion de memoria no es igual al contenido de esa direccion de memoria

Para trabajar con punteros se utilizan 2 operadores especificos:

Operador de direccion "&": Representa la direccion de memoria.
Operador de contenido "*": Representa el valor asignado a la variable apuntada.

int x = 25;


La direccion de la variable x (&x) es 1502.
El contenido de la variable es 25.

En la actualidad las computadoras utilizan muchisima memoria para ejecutar diversos procesos, seria muy complicado tratar de indicarle al programa que dirección de memoria queremos visitar, es su lugar a cada dirección de memoria se le da una etiqueta, esta etiqueta la conocemos como variable; ya que lo que nos interesa es almacenar los datos que usaremos y no dónde se localizan.

Un puntero se declara como cualquier otra variable, pero su identificador va precedido por un asterisco (*):

int *puntero;

Incluso los punteros tienen sus propias direcciones de memoria: &puntero

Hay tantos tipos de punteros, como tipos de variables y estos pueden declararse dentro se estructuras complejas, funciones, ect.
...
char dato;
char *puntero;
puntero = &dato;
...


en la variable puntero guardamos la direccion de memoria de la variable dato. puntero apunta a dato, ambos del mismo tipo.

Para entenderlo mejor podemos teclear un pequeno codigo, abrimos la terminal y escribimos

emacs -nw puntero.c

despues tecleamos el siguiente codigo:
#include<stdio.h>
int main(int argc, char *argv[]) {

  int a = 20;
  int *b;

  printf("Direccion de a: %p\n", a);      // aqui muestra la direccion donde se guardo el valor de "a"
  printf("\nDireccion de b: %p\n", b);    // aqui muestra la direccion donde se guardo el valor del apuntador "b"
  printf("\nValor de a: %d\n", a);        // lo que se almaceno en "a"
  printf("\nValor de b: %d\n", b);        // lo que hay en "b" (basura)
  printf("\nDireccion de apuntador b: %p\n", *b);  // aqui esta la direccion donde se guardo el apuntador "b"
  printf("\nMemoria de a: %p\n", &a);     // se muestra la direccion donde se almaceno "a"
  b = &a;                                 //aqui se igualan direcciones
  printf("\nNueva memoria de b: %p\n", b);
  printf("\nNueva direccion de apuntador b: %p\n", *b);
  printf("\nValor de b: %d\n", b);
  return 0;
}


Para compilar tecleamos la secuencia: gcc -o puntero puntero.c.


Se generaran algunos warnings, pero el archivo sera completamente funcional.

Para ejecutar tecleamos: ./puntero



Hay pueden ver los espacios que la computadora reserva para almacenar "a" y el puntero "b", en las ultimas líneas pueden ver como las direcciones y los bloques de memoria del puntero "b" se igualan a los de "a", pero el puntero "b" sigue conteniendo basura.
Aqui le demuestro como es que un puntero no almacena el valor del bloque de memoria, solo su dirección.

Espero les haya sido útil la información, pueden consultarme cualquier duda.

SALUDOS!!! ^_^

LENGUAJES IMPERATIVOS - Generalidades COBOL

Laboratorio de Lenguajes de Programación - Semana 8


"Su nombre proviene del acrónimo COmmon Business -Oriented Language (Lenguaje Común Orientado a Negocios).
Fue creado en el año 1960 con el objetivo de crear un lenguaje de programación universal que pudiera ser usado en cualquier ordenador, ya que en los años 1960 existían numerosos modelos de ordenadores incompatibles entre sí, y que estuviera orientado principalmente a los negocios, es decir, a la llamada informática de gestión.

FUENTE: http://es.wikipedia.org/wiki/COBOL

Esta ves estamos hablando de un lenguaje de programación que ofrece una portabilidad magnifica, nos referimos (ya quedo claro) a COBOL, un lenguaje de programación de alto nivel mostrado por primera vez por CODASYL (Conference on Data Systems Languages) en 1960. Desde entonces ellos son los encargados de proporcionar nuevos y mejores estandares de COBOL, y registrarlos ante la American National Standards Institute (ANSI).

Pero basta de historia, vamos directo a la acción.

PREPARANDONOS

COBOL es un lenguaje de programación que necesita su compilador, entonces nos encargaremos de instalar su respetivo compilador en nuestro sistema operativo UBUNTU.
Vamos a abrir una terminal, y en ella teclearemos la siguiete secuencia:

sudo apt-get install open-cobol

Si se nos pide la contraseña la tecleamos y despues se nos mostrara una ventana asi:


Aceptamos el mensaje de confirmación y esperamos a que termine la configuración.

Despues tecleamos la secuencia:

sudo apt-get install libdb4.8-dev libncurses5-dev libncursesw5-dev


Nos pedira ninguna confirmación, solo esperamos a que se instalen los paquetes.

Ahora verificaremos que nuestro compilador se haya instaldo, tecleamos en la terminal: cobc, y se debe ver algo asi:



LO PRINCIPAL

Eh de decirles que escribir en COBOL tiene su chiste, este es el segundo lenguaje que me topo con una sintaxis bastante peculiar y diferente a la mayoria de los demas.
Se les llama lenguajes de programacion porque en esencia se parecen a un idioma: tienen su sintaxis, su semántica, gramática, etc. Pero todos tienen su forma de escritura, COBOL no es la excepción, esóta es la estructura de la codificación en COBOL:


La parte (1) comprende las columnas de la 1 a la 6 ambas inclusive y se utiliza para numerar las líneas, aunque hoy en día prácticamente no se utilizan.

La parte (2) comprende la columna 7 y en ella podemos encontrar, un guión (-) que nos indica que esta línea es continuación de la anterior pero que por su tamaño ocupa mas de una línea, un asteristo (*) que nos indica que el texto que viene a continuación es un comentario y por lo tanto que el compilador lo ignore, o bien puede servir dependiendo de los compiladores para indicaciones del debug.

La parte (3) se le llama Area A comprende las columnas 8 a 11 ambas inclusive y aquí es donde se escriben los nombre de las divisiones, de las secciones, de los párrafos, los indicadores de FD (File Description) y los niveles de variables 01 y 77.

La parte (4) llamada Area B comprende desde la columna 12 a la 72 y en ellas se incluirán todas las instrucciones del programa, las lineas de las secciones y los niveles de variables mayores a 01.

La parte (5) de la columna 73 a la 80 no se utiliza y por lo tanto es ignorada por el compilador.

El punto es un signo de vital importancia en cobol ya que nos indica el final de una linea, en el han de terminar todas las secciones, divisiones y párrafos. Si al final de una linea el compilador no encuentra el punto, interpretará que la instrucción continúa hasta que aparezca el punto de fin de linea.

Al igual que en otros lenguajes, el cobol dispone de palabras reservadas que no debemos de utilizar como nombres de variables o de párrafos, además éstos no deben de exceder de 30 caracteres (depende del compilador).

Todo programa escrito en cobol, debe tener unas reglas determinadas en su forma de escritura.

Estas reglas son un estándar en la programación del Cobol, aunque no es muy utilizado por la comunidad de los programadores, dado que el uso de otros lenguajes de programación ha hecho que este tipo de reglas no sean seguidas.

Básicamente son:

* Las palabras reservadas se escriben en mayúsculas.
* Las palabras reservadas opcionales se escriben sin subrayar.
* Los símbolos obligatorios se deben incluir siempre.
* Las palabras reservadas obligatorias se escriben subrayadas.
* La información escrita por el programador, deben estar en minúsculas.
* Las partes optativas se encierran entre corchetes.
* Las partes que pueden repertirse van seguidas de tres puntos.

ESTRUCTURA DEL CODIGO

Estas son OBLIGATORIAMENTE las primeras líneas de cualquier código escrito en COBOL, son como una tarjeta de presentación, se considera la primera división del codigo.
IDENTIFICATION DIVISION.
PROGRAM-ID.               Nombre del programa.
AUTHOR.                   Nombre del autor.
INSTALLATION.             Lugar donde está instalado.
DATE-WRITTEN.             Fecha de creación.
DATE-COMPILED.            Fecha de compilación.
REMARKS.                  Comentarios.


Podemos incluir además todos los comentarios o explicaciones que creamos oportunas incluyendo, como ya mencionamos, en la columna 7 un asterisco (*) que nos indica que el compilador hará caso omiso de lo que venga a continuación, por ejemplo.
    * /////// Este programa es para hacer algo ///////
  * // atención a la sección de la fecha ////


La seguna division se refiere al ambiente de trabajo donde se ejecutara el programa escrito en cobol,
ENVIORONMENT: Describe las características que debe tener el ordenador para poder ejecutar el programa, los dispositivos de Entrada \ Salida, el compilador, etc.
No me extiendo mucho en esta division porque ya no es obligatoria al momento de escribir un codigo.

La tercera division se llama DATA DIVISION, aqui se especifica el numero y tipo de variables. El principal atributo de llama:
WORKING-STORAGE SECTION En ella declararemos todas las variables no referentes a archivos, pero que durante la ejecución del programa vayamos a utilizar.

Por ultimo, la cuarta división, llamada PROCEDURE DIVISION, donde se describe, las órdenes y operaciones que se van a realizar y el orden de las mismas.

DATOS

Las variables en COBOL tambien se declaran de una forma muy peculiar, ya que el espacio en memoria no se reserva por medio de bits, sino por medio del numero de digitos o caracteres que queremos que nuestra variable tenga, por ejempo:

A(15): "la variable "A" tiene 15 caracteres, tambien puede escribirse A PIC X(15)"
X PIC 999: "la variable "X" tiene 3 digitos, todos en base 9, osea del 0 al 999"
Y PIC 9 VALUE O: "la variable "Y" tiene un digito, en base 9 (0-9), su valor inicial el 0"
Z PIC 9V9: "la variable Z tiene 1 digito y un digito decimal, en base 9 (0-9)"
W PIC 99V999: "la variable W tiene 2 digitos y 3 digitos decimales, en base 9 (0-9)"
A PIC 99P(4): "la variable A tiene 2 digitos significativos, despues hay 4 ceros (990000)"

Estas son las declaraciones mas comunes de variables.

PROCESOS

Estas son algunas palabras reservadas para realizar algunos procedimientos:

ACCEPT: Guarda una dato desde el teclado
ADD: Se utiliza para sumar.
SUBTRACT: Se utiliza para restar.
MULTIPLY: Se utiliza para multiplicar.
DIVIDE: Se utiliza para dividir.
ROUNDED: Redondeo de cifras.
GIVING: Almacena el resultado de la operación en la variables que se le indiquen.
REMAINDER: Se utiliza junto con DIVIDE, guarda el residuo de la division

EJEMPLO

Posiblemente ya estan aburridos por toda la explicacion anterior, pero cabe mencionar todas las reglas anteriores porque son de suma importancia para lo que haremos a continuacion.
Vamos a escribir un programa que multiplique 2 numeros, sencillo pero servira para poner en practica la sintaxis de COBOL.
Abrimos la terminal y tecleamos: emacs -nw multiplicacion.cob
Tecleamos lo siguiente:
     IDENTIFICATION DIVISION.
     PROGRAM-ID. Multiplicacion.
     AUTHOR. Juan Carlos.
   
     DATA DIVISION.
     WORKING-STORAGE SECTION.
     01 X PIC 9 VALUE ZEROS.
     01 Y PIC 9 VALUE ZEROS.
     01 Res PIC 99 VALUE ZEROS.
   
     PROCEDURE DIVISION.
     CalculateResult.
         ACCEPT X.
     ACCEPT Y.
     MULTIPLY Y BY Y GIVING res.
         DISPLAY "El producto es =", res.
     STOP RUN.


Una vez que terminamos de teclear el codigo procedemos a su compilacion, escribimos en la terminal:

cobc -o multiplicacion multiplicacion.cob

Esto generará un ejectuable llamado multiplicacion, para ejecutarlo tecelamos: ./multiplicacion.
Les deberé la ejecución ya que posiblemente se topen con 6 errores al momento de la compilación, aun asi se creará el archivo ejecutable, pero al correrlo generará un fallo de segmentacion (Segmentation Fault)


Pero esperol les haya sido util la informacion y si tienen alguna duda, sugerencia pueden comentar.

SALUDOS!!! ^_^

LENGUAJES IMPERATIVOS - Generalidades Fortran

Laboratorio de Lenguajes de Programación - Semana 8

Considerado el primer lenguaje de alto nivel, fue desarrollado por IBM alla por 1950 y se ha seguido un linaje de versiones ya que ha estado en uso continuo desde ya hace mas de 50 años. Su nombre proviene del inglés "Formula Translating System", es un lenguaje de proposito general, procedural e imperativo; su uso esta mas que nada orientado a los computos matemáticos, aplicaciones científicas e ingenieria.

Es importante en el campo de la ingenieria orientada a las tecnologias de la información, ya que es el lenguaje dominante en esta rama, por lo que resulta de suma importancia que un ingeniero sepa desarrollar y modificar codigo escrito en Fortran.

La version que analizaremos sera la llamada Fortran 77, la mas nueva (Fortran 90) esta ganando popularidad poco a poco.

EMPEZANDO

Para comenzar a utilizar este lenguaje necesitamos primero instalar su compilador, existe una version bajo licencia GPL que sera la que utilizaremos en nuestro sistema operativo Ubuntu; primero abrimos nuestra terminal y teclearemos la secuencia:

sudo apt-get install gfortran


si se nos pide la contraseña de usuario la tecleamos, decimos que si a todos los mensajes de confirmación y esperamos a que se descarguen, actualicen e instalen todos los paquetes necesarios.

Una vez terminada la instalacion procedemos a realizar una prueba de que el compilador se ha instalado correctamente, para ello tecleamos en la terminal:

gfortran


Veremos que aparecera un mensaje que dice gfortran: no input files, esto se refiere a que llamamos al compilador pero no encontro ningun código fuente el cual compilar, con esto nos aseguramos que el compilador se ha instalado.
Los códigos fuente escritos en Fortran se guardan con la terminación *.f

BASICOS

Como en cualquier otro lenguaje de programación, en Fortran a las variables se les declara con un grupo de caratéres y números, aunque el primer caractér debe ser forzozamente una letra.
Los tipos de datos soportados por fortran son:

integer - enteros
real - cualquier numero real (punto flotante [decimales])
double precision - equivalente a DOUBLE en c
complex - numeros complejos
logical - equivalente a BOOLEAN
character - caracteres (letras, cadenas)

Fortran no hace distincion entre mayúsculas y minúsculas pero es altamente recomendable realizar toda la escritura en mayúscula (existen compiladores que envian mensajes de error si encuentran datos en minúsculas); también existen las llamadas "palabras reservadas" como "program", "stop" y "end" (algo equivalente a int, void, main, define, import, int, etc, en lenguaje C).

OPERACIONES BÁSICAS

Las operaciones aritmÉticas en Fortran no distan mucho de las declaraciones en C.


Otros ejemplos


Para practicar la aritmética en Fortran, teclearemos un programita sencillo que pida dos valores y haga diferentes operaciones con ellos.
Primero abrimos nuestra terminal y tecleamos:

emacs -nw aritmetica.f

Despues procedemos a teclear lo siguiente:
     PROGRAM aritmetica
    
     REAL x, y, s, r, m, d, p
    
     PRINT*, 'Dame el primer valor : '
     READ(*,*) x
     PRINT*, 'Dame el segudo valor: '
     READ(*,*) y
    
     s = x+y
     r = x-y
     m = x*y
     d = x/y
     p = x**y

     WRITE(*,*) 'SUMA: ', s, 'RESTA: ', r
     WRITE(*,*) 'PRODUCTO: ', m, 'DIVISION: ', d
     WRITE(*,*) 'POTENCIA: ', p

     STOP
     END


**LOS PROGRAMAS EN FORTRAN SIEMPRE EMPIEZAN CON UNA IDENTACIÓN DE 7 ESPACIOS, SI NO SE SIGUE ESTA REGLA EL COMPILADOR MARCARA ERROR HASTA QUE CORRIJAN ESE DETALLE, EMACS INCLUYE IDENTACION AUTOMATICA Y RESALTADO PARA FORTRAN

Una vez que tecleamos el código anterior procedemos a su compilacion, tecleamos en la terminal la secuencia:

gfortran -o aritmetica aritmetica.f (gfortran es el compilador, "-o artimetica" es para especificar el nombre del archivo de salida, "aritmetica.f" es el codigo fuente)

Y para ejecutar tecleamos: ./aritmetica


Para el siguiente ejemplo, teclearemos un programa que calcule la sumatoria y por ende el promedio de 5 numeros.
Abrimos nuestra terminal y tecleamos:

emacs -nw promedio.f

Despues procedemos a teclear lo siguiente:
     PROGRAM promedio

     INTEGER i, j
     REAL x, sum, prom
     j = 5
     sum = 0
     prom = 0

     DO 10 i=1, j
        WRITE(*,*) 'Dame valor',i, ':'
        READ(*,*) x
        sum = sum+x
10   CONTINUE
   
     prom = sum / j

     WRITE(*,*) 'Sumatoria: ', sum, 'Promedio: ', prom
     STOP
     END


Nos fijamos haber agregado bien la identación, si se fijan en este programa utilice un ciclo DO, en Fortran se cierran los ciclos mediante banderas, es decir, en el programa el ciclo DO se ejecutara hasta encontrar la bandera 10 (DO 10), la bandera esta lineas mas abajo en el primer espacio de la identación seguda de 6 espacios y la palabra reservada CONTINUE. Las primeras 5 posiciones de la identación estan separadas en Fortran para este y otros tipos de banderas

Una vez que tecleamos el código anterior procedemos a su compilacion, tecleamos en la terminal la secuencia:

gfortran -o promedio promedio.f

Y para ejecutar tecleamos: ./promedio



Espero les haya sido util esta informacion. En la barra de "RECURSOS" esta un buen tutorial (en inglés :(), que me sirvió bastante para el desarrollo de esta práctica.

SALUDOS!!! ^_^

domingo, 31 de octubre de 2010

PROLOG - Horario de Clase

Lenguajes de Programación - Semana 9 - PUNTOS EXTRA

Se plantea el siguiente acertijo:

”Un alumno de ITS, debido al nerviosismo del primer día de clase, ha anotado el nombre de sus profesores (Elisa, Fernando y Carlos), las asignaturas que se imparten (Lógica, Programación y Matemáticas) y el día de la semana de las distintas clases (lunes, miércoles y viernes), pero sólo
recuerda que:
- La clase de Programación, impartida por Elisa, es posterior a la de Lógica
- A Carlos no le gusta trabajar los lunes, día en el que no se imparte Lógica
Ayudale a relacionar cada profesor con su asignatura, así como el día de la semana que se imparte
(Sabemos que cada profesor imparte una única asignatura y que las clases se dan en días diferentes)”


Analicemos el problema mentalmente:

Tenemos 3 materias:

Lógica
Programación
Matemáticas


Tenemos 3 dias:

Lunes
Miércoles
Viernes


Tenemos 3 maestros:

Elisa
Carlos
Fernando


Con base a la redacción del problema tenemos las siguientes proposiciones:

Elisa da programación.
Carlos no trabaja el lunes.
El lunes no hay clase se Lógica.
Programación se imparte cualquier día posterior al Lunes.


Para acomodar los días en que se imparte cada materia sabemos solamente que los lunes no hay lógica, como programacón se da el día posterior a lógica entonces no puede impartirse el miércoles , y aunque necesitamos un día anterior ese día anterior no puede ser el lunes, entonces las materias se imparten en el siguiente orden:

Matemáticas los Lunes
Lógica los Miércoles
Programación los Viernes


Como Carlos no trabaja los lunes entonces solo le queda el miércoles para impartir clase porque Elisa le gan&ocute; los viernes, a Fernando no le qued&ocute; de otra mas que dar matemáticas. Entonces la respuesta al problema es:

Fernando da Matemáticas los Lunes
Carlos da Lógica los Miércoles
Elisa da Programación los Viernes


Analicemos el problema en PROLOG:

Primero convertimos cada una de las proposiciones en hechos:

materia(logica).
materia(programacion).
materia(matematicas).
maestro(elisa).
maestro(fernando).
maestro(carlos).
dia(lunes).
dia(miercoles).
dia(viernes).


Tendremos 3 formatos de respuesta diferentes:

imparte(X,Y) "Profesor X imparte la materia Y"
trabaja(X,Z) "Profesor X trabaja el día Z"
clase(Y, Z) "Hay clase Y el dia Z"

Tenemos la siguientes proposiciones predefinidas:

imparte(elisa, programacion). "Elisa imparte programacón"

Entonces para saber que maestro va el resto de las materias aplicaremos la siguiente regla:

imparte(X, Y) :- maestro(X), X\=elisa, materia(Y), imparte(elisa,YA), YA\=Y. "Sera verdad si hay un maestro X, a excepcion de Elisa; y existe una materia Y. Sacamos a Elisa de este conjunto porque ya sabemos que clase imparte, además recursivamente quitaremos el curso que imparte Elisa."

Sabemos tambien que Carlos ira cualquier día que no sea lunes, entonces:

trabaja(carlos, Z) :- dia(Z), Z\=lunes. " Carlos trabaja algún día Z, a excepción del Lunes"

La regla general queda:

trabaja(X, Z) :- maestro(X), X\=carlos, dia(Z), Z\=miercoles. "Sera verdad si hay un maestro X, quitando a Carlos, un dia Y. Quitamos a Carlos porque ya sabemos que lunes no va y los miercoles porque Carlos no va lunes y el viernes es de Elisa"

Tambien tenemos conocimento de que la clase de lógica no se da los lunes, entonces:

clase(logica, Z) :- dia(Z), Z\=lunes, Z\=viernes. "Sera verdad que logica se imparte el dia Z, si ese dia no es lunes o viernes; porque el lunes no aplica y el viernes tampoco puesto que sabemos hay una clase delante de ella"

clase(programacion, Z) :- dia(Z), Z\=lunes, clase(logica, ZA), ZA\=Z. "Sera verdad que programación se da un día Z, si ese día no es lunes; porque sabemos que hay una clase anterior a ella. Recursivamente quitamos el día en el que lógica puede impartirse"

La regla general queda:

clase(Y, Z) :- materia(Y), Y\=logica, Y\=programacion, clase(logica, ZA), clase(programacion, ZB), dia(Z), ZA\=Z, ZB\=Z. "Sera verdad si hay una materia Y que no sea lógica o programación, y cualquier día de la semana que no sean los días en que se imparte lógica y programación"

PROGRAMA COMPLETO

materia(logica).
materia(programacion).
materia(matematicas).
maestro(elisa).
maestro(fernando).
maestro(carlos).
dia(lunes).
dia(miercoles).
dia(viernes).
imparte(elisa, programacion).
imparte(X, Y) :- maestro(X), X\=elisa, materia(Y), imparte(elisa, YA), YA\=Y.
trabaja(carlos, Z) :- dia(Z), Z\=lunes.
trabaja(X, Z) :- maestro(X), X\=carlos, dia(Z), Z\=miercoles.
clase(programacion, Z) :- dia(Z), Z\=lunes, clase(logica, ZA), ZA\=Z.
clase(logica, Z) :- dia(Z), Z\=lunes, Z\=viernes.
clase(Y, Z) :- materia(Y), Y\=logica, Y\=programacion, clase(programacion, ZA), clase(logica, ZB), dia(Z), ZA\=Z, ZB\=Z.


Abrimos un archivo en emacs y lo llamaremos "horario.pro" (en terminal tecleamos: emacs -nw horario.pro ), tecleamos el código que les acabo de mostrar y guardamos todo.
Despues procedemos a abrir el interprete SWI-PROLOG:


Posteriormente cargamos el código que acabmos de guardar:


** OPCIONALMENTE PODEMOS TECLEAR LA OPCION listing. PARA VER LA CARGA DEL ARCHIVO, YO LA OMITO PORQUE LA IMAGEN ES MUY LARGA PARA ESTA ENTRADA.

Ahora evaluamos el problema, en este caso hay que concatenar todas nuestras preguntas para que se evalún juntas, si las ponemos separadas solo se nos mostraran todas las combinaciones de maestros, días y clases, pueden probarlo si quieren; asi evaluaremos toda la pregunta completa:

imparte(X,Y),trabaja(X,Z),clase(Y,Z).

Y este es el resultado:


Como ven, el resultado es el horario armado tal como la respuesta que obtuvimos analíticamente.

PD: La "a" al lado de la respuesta de Elisa la teclee yo, sirve para mostrar toda la lista de resultados sin tener que aplanar la tecla ";" para listar respuesta tras respuesta.

SALUDOS!!! ^_^