/* Gramatica problema Trenes */ /* Esta solucion es solo a nivel ilustrativo y no debe tomarse como 'la solucion'. Esto es un programa prolog que deberia ejecutarse sin problemas en cualquier interprete de prolog estandar. Para ejecutar las frases del enunciado podeis ejecutar el predicado go, que presentara el resultado del analisis de las frases correctas y no presentara nada para las incorrectas. */ /* La representacion es muy sencilla, un predicado que tiene parametros para toda la informacion que puede aparecer, podeis hacer representaciones mas complejas en las que no aparezca la informacion que no salga en la frase, en este caso, si no sale la informacion la variable quedara sin vincular. Caso especial es la informacion sobre origen y destino, si no aparece se vincula al atomo 'vacio'. La representacion es: tren(Tipo= el que corresponda, Origen= el que corresponda o el atomo 'vacio', Destino= el que corresponda o el atomo 'vacio', Direccion= 'salida', o 'llegada', Via= un numero, Hora= el texto que aparezca, Paradas= lista de paradas o 'todas' o 'ninguna', Retraso= un numero */ analisis(F,X,Y) :- asercion(F,X,Y). /* Estructuramos la informacion en (tipo de tren, destino-origen, salida o llegada, mas informacion) */ asercion(tren(Tipo,Origen,Destino,Direccion,Via,Hora,Paradas,Retraso)) --> tipo_tren(Tipo),de_donde_a_donde(Origen,Destino), viene_o_va(Origen,Destino,Direccion), mas_info(Via,Hora,Paradas,Retraso,Destino). tipo_tren(Tipo) --> nombre_tren(Tipo). /* En el caso de que solo aparezca destino u origen la otra variable se vincula a vacio. Hay otra solucion que es no vincular la variable y usar los predicados nonvar(X) y var(X), que nos dicen si una variable esta vinculada o no */ de_donde_a_donde(Origen,Destino) --> procedente_de(Origen),con_destino(Destino). de_donde_a_donde(Origen,vacio) --> procedente_de(Origen). de_donde_a_donde(vacio,Destino) --> con_destino(Destino). procedente_de(Origen) --> [procedente,de], es_ciudad(Origen). con_destino(Destino) --> [con,destino], es_ciudad(Destino). /* Aqui comprobamos si hay destino con salida y origen con llegada, Damos preferencia al destino, es decir si hay origen y destino ha de decir que sale. */ viene_o_va(_,Destino,salida) --> {Destino \== vacio}, [efectuara,su,salida]. viene_o_va(Origen,_,llegada) --> {Origen \== vacio}, [efectuara,su,llegada]. /* El resto de la informacion la dividimos en dos, el retraso por un lado, y la via, la hora y las paradas por otro, pasamos tambien el destino para saber si es correcto que aparezcan paradas o no. Se puede hacer tambien con los predicados var(X) y nonvar(X) sin tener que pasar esta variable */ mas_info(_,_,_,Retraso,_) --> [con,un,retraso,de],numero(Retraso),[minutos]. mas_info(Via,Hora,Paradas,_,Destino) --> via_hora(Via,Hora), con_paradas(Paradas,Destino). via_hora(Via,Hora) --> por_via(Via), a_la_hora(Hora). via_hora(Via,Hora) --> a_la_hora(Hora), por_via(Via). por_via(Via) --> [por,via], es_via(Via). a_la_hora(Hora) --> [a,las], es_hora(Hora). /* Hay cuatro posibles paradas en las que el destino no puede ser vacio, y el caso en el que no hay nada */ con_paradas(ninguna,Destino) --> {Destino \== vacio}, coma, [no,efectuara,paradas]. con_paradas(todas,Destino) --> {Destino \== vacio}, coma, [para,en,todas,las,estaciones]. con_paradas(Parada,Destino) --> {Destino \== vacio}, coma, [para,en,la,estacion,de], lista_ciudades(Parada), {length(Parada,1)}. /* Solo puede haber una ciudad */ con_paradas(Parada,Destino) --> {Destino \== vacio}, coma, [para,en,las,estaciones,de], lista_ciudades(Parada), {length(Parada,N), N>1}. /* Ha de haber mas de una ciudad */ con_paradas(_,_) --> []. /* Extraemos la lista de ciudades */ lista_ciudades([C|C2]) --> es_ciudad(C), mas_ciudades(C2). lista_ciudades([C]) --> es_ciudad(C). mas_ciudades([C]) --> y , es_ciudad(C). mas_ciudades([C|C2]) --> coma, es_ciudad(C), mas_ciudades(C2). /* Terminales */ nombre_tren(Tipo) --> [Tipo],{n_tren(Tipo)}. /* Trenes de una palabra */ nombre_tren(Tipo) --> [W1,W2],{n_tren(W1,W2,Tipo)}. /* Trenes de dos palabras */ es_ciudad(W) --> [W],{ciudad(W)}. es_via(W) --> [W],{number(W)}. numero(W) --> [W],{number(W)}. es_hora(W) --> [W]. /* Pasamos de comprobar que eso es una hora */ coma --> [',']. y --> [y]. /* Lexicon */ n_tren(talgo). n_tren(cercanias). n_tren(regional). n_tren(intercity). n_tren(largo,recorrido,largo_recorrido). ciudad(mataro). ciudad(barcelona). ciudad(girona). ciudad(pamplona). ciudad(paris). ciudad(valencia). ciudad(alicante). ciudad(bilbao). ciudad(tarragona). ciudad(murcia). ciudad(ginebra). ciudad(madrid). ciudad(malaga). ciudad(almeria). /* Frases de prueba */ go :- frase(X),write(X),nl,nl,analisis(F,X,[]),write('Resultado: '),write(F),nl,nl,fail. /* Las frases del enunciado */ frase([cercanias,procedente,de,mataro,con,destino,barcelona,efectuara,su,salida,por,via,5,a,las,15:30]). frase([regional,procedente,de,valencia,efectuara,su,llegada,a,las,18:00,por,via,7]). frase([largo,recorrido,procedente,de,madrid,efectuara,su,llegada,con,un,retraso,de,20,minutos]). frase([talgo,con,destino,malaga,efectuara,su,salida,a,las,14:30,por,via,8,',',no,efectuara,paradas]). frase([regional,procedente,de,girona,con,destino,tarragona,efectuara,su,salida,a,las,18:00,por,via,9,',',para,en,todas,las,estaciones]). frase([intercity,procedente,de,tarragona,con,destino,almeria,efectuara,su,salida,a,las,10:00,por,via,2,',',para,en,las,estaciones,de,valencia,',',alicante,y,murcia]). frase([talgo,con,destino,ginebra,efectuara,su,salida,con,un,retraso,de,15,minutos]). frase([regional,con,destino,bilbao,efectuara,su,salida,a,las,16:30,por,via,1,',',para,en,la,estacion,de,pamplona]). /* procedencias con salida y destinos con llegada */ frase([cercanias,procedente,de,mataro,efectuara,su,salida,por,via,8,a,las,19:00]). frase([talgo,con,destino,paris,efectuara,su,llegada,a,las,19:00,por,via,6]). /* No hay destino y se habla de paradas */ frase([intercity,procedente,de,barcelona,efectuara,su,llegada,a,las,19:00,por,via,3,',',no,efectuara,paradas]). /* Una parada con plural y varias paradas con singular */ frase([regional,con,destino,valencia,efectuara,su,llegada,a,las,19:00,por,via,3,',',para,en,la,estacion,de,murcia,y,alicante]). frase([regional,con,destino,valencia,efectuara,su,llegada,a,las,19:00,por,via,3,',',para,en,las,estaciones,de,murcia]).