Ezequiel Berto
Ezequiel Berto

Reputation: 130

Can't validate input in PROLOG

I've made an Expert System but I have some bugs. It works asking the user some questions, who answers 'yes' or 'no' ('si', 'no' in Spanish). The thing is that when I validate the answer, the program returns "false". Here's the part of code with the error:

:- dynamic respondeSi/1.
:- dynamic respondeNo/1.
:- dynamic seriesSugeridas/2.

abrirBase :-
   retractall(seriesSugeridas(_,_)),
   retractall(respondeSi(_)),
   retractall(respondeNo(_)),
   consult('TP4.txt').  %modificar directorio

inicio:- 
   abrirBase, writeln('¡Bienvenido! Vamos a ver qué serie podemos recomendarte...'), 
   filtrar_series.

filtrar_series:- 
   preguntar_duracion(RtaDuracion),
   preguntar_serie_terminada(RtaTermino),
   preguntar_serie_nueva(RtaSerieNueva), 
   obtener_series(RtaDuracion, RtaTermino, RtaSerieNueva), 
   consultar_caracteristicas.

preguntar_duracion(RtaDuracion):-  
   write('¿Tenés bastante tiempo libre? Respuesta (si|no): '),  
   read(RtaDuracion),  RtaDuracion \= si, RtaDuracion \= no, 
   writeln('Respuesta inválida, conteste nuevamente.'), 
   preguntar_duracion(RtaDuracion).  
   %%AFTER INPUTTING THE ANSWER ONCE MORE HERE, 
     IT RETURNS "false" AND ENDS THE PROGRAM

preguntar_serie_terminada(RtaTermino):-  
   write('¿Buscás una serie que aún no haya terminado? Respuesta (si|no): '),  
   read(RtaTermino),  RtaTermino \= si, RtaTermino \= no, 
   writeln('Respuesta inválida, conteste nuevamente.'),  
   preguntar_serie_terminada(RtaTermino).

preguntar_serie_nueva(RtaSerieNueva):-  
   write('¿Buscás una serie nueva? Respuesta (si|no): '), 
   read(RtaSerieNueva),  RtaSerieNueva \= si, RtaSerieNueva \= no, 
   writeln('Respuesta inválida, conteste nuevamente.'),  
   preguntar_serie_nueva(RtaSerieNueva).

Why does it happen? Thanks

UPDATE: it will ALWAYS return false. I'm quite sure that false is the output of RtaDuracion \= si.

Upvotes: 1

Views: 505

Answers (1)

Fatalize
Fatalize

Reputation: 3543

I don't really speak spanish and can't test your code, but from what I see the problem lies in preguntar_duracion(RtaDuracion):

preguntar_duracion(RtaDuracion):-  
   write('¿Tenés bastante tiempo libre? Respuesta (si|no): '),  
   read(RtaDuracion),  RtaDuracion \= si, RtaDuracion \= no, 
   writeln('Respuesta inválida, conteste nuevamente.'), 
   preguntar_duracion(RtaDuracion).  

From what I understand, read(RtaDuracion) expects si or no as answer. The problem is that you only define the behavior when the input is invalid, and not when it is actually valid. Which means, that when you input si or no, it will not satisfy the rule and simply fail.

Moreover, if the input is invalid, you then recursively call preguntar_duracion with the RtaDuracion you just read. Which means that for the next read, it will already have a value for RtaDuracion and will thus fail if the user inputs something else. And this will go on forever if you always input the same thing.

You could correct this predicate like this, using the if -> then ; else construct of Prolog:

preguntar_duracion(RtaDuracion):-  
   write('¿Tenés bastante tiempo libre? Respuesta (si|no): '),
   read(TempRtaDuracion),
   (   TempRtaDuracion \= si,
       TempRtaDuracion \= no
   ->  writeln('Respuesta inválida, conteste nuevamente.'), 
       preguntar_duracion(RtaDuracion)
   ;   RtaDuracion = TempRtaDuracion
   ).

Upvotes: 2

Related Questions