Buscando al asesino en Prolog

Todos los domingos en nuestra empresa es costumbre organizar divertidos cuestionarios, este es uno de ellos.

Acertijo


Para encontrar al asesino del Sr. Boddy, debes averiguar dónde estaba cada persona y qué armas había en la habitación. Las sugerencias se encuentran dispersas a lo largo de la prueba (no puede responder la primera pregunta hasta que haya leído las diez).

  • Primero, imagina a los sospechosos. Hay tres hombres (George, John, Robert) y tres mujeres (Barbara, Christina, Yolanda). Cada persona se encuentra en una habitación separada (baño, comedor, cocina, sala de estar, despensa, oficina). Se encontraron armas sospechosas en cada habitación (bolsa, arma de fuego, gas, cuchillo, veneno, soga). Pregunta: ¿quién fue encontrado en la cocina?
  • Consejo 1. Con un hombre en la cocina no hay ni una cuerda, ni un cuchillo, ni una bolsa. El arma no es un arma de fuego. Pregunta: ¿Qué armas se encontraron en la cocina?

  • Sugerencia 2. Barbara está en el estudio o en el baño, y Yolanda está en otra de las dos habitaciones nombradas. ¿En qué habitación encontró Barbara?
  • Consejo 3. El hombre de la bolsa no es ni Bárbara ni George, y no estaba en el baño ni en el comedor. ¿Quién tenía la bolsa?
  • Consejo 4. Una mujer con una cuerda fue encontrada en la oficina. Quien es ese
  • Consejo 5. El arma en la sala de estar pertenece a John o George. ¿Qué tipo de arma en la sala de estar?
  • Consejo 6. No había cuchillo en el comedor. ¿Dónde estaba el cuchillo?
  • Sugerencia 7. Yolanda no estaba en la oficina ni en la despensa con las armas apropiadas para estas habitaciones. ¿Qué tipo de arma tiene Yolanda?
  • Consejo 8. George encontró un arma de fuego. Cual habitacion
  • Se descubrió que el Sr. Boddy fue gaseado en la despensa. El sospechoso en esa habitación era un asesino. Quien es este

Me esfuerzo por tales acertijos (en realidad de casi cualquier acertijo). Podrían tomar horas y horas de reflexión, ¡pero Prolog siempre viene al rescate! Veamos cómo ayuda resolver estos problemas de razonamiento.

Prolog 101


Instalar SWI-Prolog


~> swipl Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.6.6) Copyright (c) 1990-2013 University of Amsterdam, VU Amsterdam SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. Please visit http://www.swi-prolog.org for details. For help, use ?- help(Topic). or ?- apropos(Word). ?- write('Hello, World!'). Hello, World! true. ?- write('Hello,'), nl, write('world'). Hello, world true. ?- X is 3*4 + 2. X = 14. 

  • swipl - intérprete de Prolog
  • write se llama functor, y la representación write/1 significa que se necesita 1 argumento (el mismo concepto en Erlang y Elixir para agregar el número de argumentos a un nombre de función)
  • nl usa para imprimir una nueva línea
  • la secuencia de comandos está separada por comas, que también reemplazan al operador AND
  • el operador de asignación is seguido por una expresión matemática
  • las variables se escriben en X mayúscula, no x

Base de conocimiento


La esencia de Prolog está en declarar hechos, compilar hechos y solicitarlos.

Crear el archivo hello.pl :

 friend(john, julia). friend(john, jack). friend(julia, sam). friend(julia, molly). loves(john, julia). loves(julia, sam). loves(sam, julia). male(brad). male(john). male(jim). male(alfred). female(marry). child(brad, alfred). child(john, jim). child(john, marry). 

  • usamos [hello]. para cargar [hello]. : preste atención al punto al final
  • listing enumera todos los hechos en la base de conocimiento

 ?- [hello]. % hello compiled 0.00 sec, 3 clauses true. ?- listing(friend). friend(john, julia). friend(john, jack). friend(julia, sam). friend(julia, molly). true. ?- listing(loves). loves(john, julia). loves(julia, sam). loves(sam, julia). true. 

Solicitud de hechos


Después de exponer los hechos en la base de conocimiento, podemos ir más allá y hacer preguntas sobre la verdad de los hechos, así como también qué conclusiones se pueden sacar de ellos.

 ?- friend(john, julia). true . ?- friend(john, jack). true. ?- loves(john, julia). true. ?- loves(john, sam). false. 

Podemos hacer preguntas más complejas. Por ejemplo, quién es amigo de John o quién ama a Julia.

 ?- friend(john, Who). Who = julia ; Who = jack. 

 ?- listing(child). child(brad, alfred). child(john, jim). child(john, mary). true. ?- child(john, X). X = jim ; X = mary. 

¿Está John en la zona de amigos?


Hemos establecido la amistad de John con Julia ( friend(john, julia) ), pero para Prolog esto no significa que Julia sea amiga de John: debe agregar otro hecho friend(julia, john) . También hemos indicado quién tiene hijos y, obviamente, no desea duplicar el código, indicando por separado los padres de cada niño. No queremos escribir algo como

 child(brad, alfred). child(john, jim). child(john, mary). parent(alfred, brad). parent(jim, john). parent(mary, john). 

Prolog ayuda a evitar la duplicación con reglas de conclusión lógicas:

 rule :- stmt1, stmt2,... 

La regla es verdadera si todas las declaraciones internas son verdaderas (enumeradas y lógicamente dobladas con una coma).

 friend(X, Y) :- friend(Y,X). parent(X, Y) :- child(Y,X). father(X, Y) :- child(Y,X), male(X). mother(X, Y) :- child(Y,X), female(X). friendzoned(X) :- loves(X, Y), \+ loves(Y,X). 

  • friend(X,Y) cierto para friend(Y,X )
  • parent(X,Y) verdadero cuando se establece child(Y,X)
  • father(X,Y) cierto con el conjunto parent(X,Y) y male(X)
  • mother(X,Y) verdadero cuando female(X) parent(X,Y) y female(X)
  • friendzoned(X) cierto si X ama a SOMEONE Y e Y no ama a X (¿nota la variable oculta Y?)

 ?- friend(julia, john). true . ?- male(jim). true. ?- parent(jim,X). X = john. ?- father(jim, X). X = john. ?- mother(X, john). X = marry. ?- mother(marry,X). X = john. ?- mother(marry, john). true. ?- loves(julia, X). X = sam. ?- friendzoned(julia). false. ?- friendzoned(john). true. 

Ok, ahora tenemos todo el conocimiento necesario. Practiquemos sobre la coloración del mapa.

Coloración de la tarjeta


Comencemos con el conocido problema matemático. Se requiere que ninguna área adyacente tenga el mismo color.



Por lo tanto, el razonamiento debe ser tal, tenemos tres cosas:

  1. Las variables son las áreas que queremos colorear: A, B, C, D, E.
  2. Dominio: un rango de valores que se pueden asignar a las variables: rojo, azul, verde.
  3. La limitación es que las áreas adyacentes no pueden ser del mismo color.

Dominio


Definir el dominio de nuestras regiones (rojo, verde, azul).

 color(red). color(green). color(blue). 

Eso es todo

Pedimos una solución


 colorify(A,B,C,D,E) :- color(A), color(B), color(C), color(D), color(E), \+ A=B, \+ A=C, \+ A=D, \+ A=E, \+ B=C, \+ C=D, \+ D=E. 

Aquí definimos la solución como una regla de colorify con cinco variables A, B, C, D, E, y dentro de la regla asignamos el color de dominio (rojo, azul, verde) para las variables y establecemos las restricciones de que A no es igual a B, no es igual a C ... y etc.

\+ X=Y significa que X no es igual a Y

Prolog continuará generando valores hasta que encuentre una opción que satisfaga la regla con restricciones.

 ?- [mapcoloring] | . true. ?- colorify(A,B,C,D,E) | . A = red, B = D, D = green, C = E, E = blue ; A = red, B = D, D = blue, C = E, E = green ; A = green, B = D, D = red, C = E, E = blue ; A = green, B = D, D = blue, C = E, E = red ; A = blue, B = D, D = red, C = E, E = green ; A = blue, B = D, D = green, C = E, E = red 

 color(red). color(green). color(blue). colorify(A,B,C,D,E) :- color(A), color(B), color(C), color(D), color(E), \+ A=B, \+ A=C, \+ A=D, \+ A=E, \+ B=C, \+ C=D, \+ D=E. 

... pero no estamos coloreando las imágenes aquí, sino buscando al asesino.

La matanza


Primero, imagina a los sospechosos. Hay tres hombres (George, John, Robert) y tres mujeres (Barbara, Christina, Yolanda). Cada persona se encuentra en una habitación separada (baño, comedor, cocina, sala de estar, despensa, oficina). Se encontraron armas sospechosas en cada habitación (bolsa, arma de fuego, gas, cuchillo, veneno, soga).

¿Quién fue encontrado en la cocina?

Dominio


De esto podemos concluir que tenemos cinco dominios: man , woman , person o sospechoso, location y weapons , y nuestras variables (A, B, C, D, E, F) deben representar a la persona, el lugar y el arma. con algunas limitaciones que se revelarán en los próximos consejos.

 man(george). man(john). man(robert). woman(barbara). woman(christine). woman(yolanda). person(X):- man(X). person(X):- woman(X). location(bathroom). location(dining). location(kitchen). location(livingroom). location(pantry). location(study). weapon(bag). weapon(firearm). weapon(gas). weapon(knife). weapon(poison). weapon(rope). 

La regla uniq_ppl genera valores únicos para nuestras variables.

 uniq_ppl(A,B,C,D,E,F):- person(A), person(B), person(C), person(D), person(E), person(F), \+A=B, \+A=C, \+A=D, \+A=E, \+A=F, \+B=C, \+B=D, \+B=E, \+B=F, \+C=D, \+C=E, \+C=F, \+D=E, \+D=F, \+E=F. 

Solución


Comenzamos definiendo la regla de un asesino con personas únicas en lugares y personas únicas con armas, y ahora indicaremos la relación entre personas en lugares con aquellos que tienen armas.

Tenga en cuenta que todavía tenemos seis sospechosos.

Entrada


 murderer(X) :- uniq_ppl(Bathroom, Dining, Kitchen, Livingroom, Pantry, Study), uniq_ppl(Bag, Firearm, Gas, Knife, Poison, Rope), 

Para hablar fácilmente sobre variables, como el baño, el comedor, las armas de fuego, el gas, determinamos de inmediato:

  • Baño: es el mismo sospechoso (hombre o mujer) en el baño
  • Armas de fuego: es el mismo sospechoso (hombre o mujer) con arma de fuego
  • y así sucesivamente ... puedes imaginarlo como una cuadrícula

Ahora seguimos agregando restricciones después de la última coma en la regla del murderer .

Consejo 1


Con un hombre en la cocina no hay cuerda, cuchillo o bolsa. El arma no es un arma de fuego. ¿Qué armas se encuentran en la cocina?

 % 2. Clue 1: The man in the kitchen was not found with the rope, knife, or bag. % Which weapon, then, which was not the firearm, was found in the kitchen? man(Kitchen), \+Kitchen=Rope, \+Kitchen=Knife, \+Kitchen=Bag, \+Kitchen=Firearm, 

Aquí decimos que la variable Kitchen satisface el hecho del man (definido en nuestro dominio), y declaramos que no importa quién sea la persona en la cocina, él no tiene ninguno de los siguientes: Rope , Knife , Bag , Firearm .

Pista 2


Sugerencia 2. Barbara está en el estudio o en el baño, y Yolanda está en otra de las dos habitaciones nombradas. ¿En qué habitación encontró Barbara?

Por lo tanto, podemos decir que hay una woman en la oficina y en el baño, y esta no es Christina, y también tachamos las otras opciones para Barbara y Yolanda (cocina, comedor, sala de estar, despensa).

 % % 3. Clue 2: Barbara was either in the study or the bathroom; Yolanda was in the other. % % Which room was Barbara found in? woman(Bathroom), woman(Study), \+christine=Bathroom, \+christine=Study, \+barbara=Dining, \+barbara=Kitchen, \+barbara=Livingroom, \+barbara=Pantry, 

Consejo 3


El hombre de la bolsa no es ni Barbara ni George, y no estaba en el baño ni en el comedor. ¿Quién tenía la bolsa?

 % % 4. Clue 3: The person with the bag, who was not Barbara nor George, was not in the bathroom nor the dining room. % % Who had the bag in the room with them? \+barbara=Bag, \+george=Bag, \+Bag=Bathroom, \+Bag=Dining, 

Consejo 4


Una mujer con una cuerda fue encontrada en la oficina. Quien es ese

 % % 5. Clue 4: The woman with the rope was found in the study. % % Who had the rope? woman(Rope), Rope=Study, 

Consejo 5


Consejo 5. El arma en la sala de estar pertenece a John o George. ¿Qué tipo de arma en la sala de estar?

 man in Livingroom Livingroom isn't robert % % 6. Clue 5: The weapon in the living room was found with either John or George. % % What weapon was in the living room? man(Livingroom), \+Livingroom=robert, 

Consejo 6


No había cuchillo en el comedor. ¿Dónde estaba el cuchillo?

 % % 7. Clue 6: The knife was not in the dining room. % % So where was the knife? \+Knife=Dining, 

Consejo 7


Pista 7. Yolanda no estaba en la oficina ni en la despensa. ¿Qué arma hay en la habitación de Yolanda?

 % % 8. Clue 7: Yolanda was not with the weapon found in the study nor the pantry. % % What weapon was found with Yolanda? \+yolanda=Pantry, \+yolanda=Study, 

Consejo 8


George encontró un arma de fuego.

 % % 9. Clue 8: The firearm was in the room with George. % % In which room was the firearm found? Firearm=george, 

Consejo 9


Se descubrió que el Sr. Boddy fue gaseado en la despensa. El sospechoso en esa habitación era un asesino. Quien es ese

 % % 10. It was discovered that Mr. Boddy was gassed in the pantry. The suspect found in that room was the murderer. % % Who, then, do you point the finger towards? Pantry=Gas, Pantry=X, write("KILLER IS :"), write(X), nl, writeanswers(Bathroom, Dining, Kitchen, Livingroom, Pantry, Study, Bag, Firearm, Gas, Knife, Poison, Rope). 

writeanswers coincidir el gas, la despensa y el asesino, luego use write para write writeanswers write .

 writeanswers(Bathroom, Dining, Kitchen, Livingroom, Pantry, Study, Bag, Firearm, Gas, Knife, Poison, Rope):- write("Bathroom: "), write(Bathroom), nl, write("Dining: "), write(Dining), nl, write("Livingroom: "), write(Livingroom), nl, write("Pantry: "), write(Pantry), nl, write("Study: "), write(Study), nl, write("Kitchen: "), write(Kitchen), nl, write("Knife: "), write(Knife), nl, write("Gas: "), write(Gas), nl, write("Rope: "), write(Rope), nl, write("Bag: "), write(Bag), nl, write("Poison: "), write(Poison), nl, write("Firearm: "), write(Firearm), nl. 

¿Quién es el asesino?


  ?- [crime2]. true. ?- murderer(X). KILLER IS :christine Bathroom: yolanda Dining: george Livingroom: john Pantry: christine Study: barbara Kitchen: robert Knife: yolanda Gas: christine Rope: barbara Bag: john Poison: robert Firearm: george X = christine ; 

El código se publica aquí . Probablemente podría haber sido mucho mejor ya que no soy un experto en Prolog :)

Source: https://habr.com/ru/post/es434172/


All Articles