Pregunta

Tengo que simular árbol familiar en Prolog. Y tengo un problema de predicados simétricos. Datos:

parent(x,y).
male(x).
female(y).
age(x, number).

Reglas:

blood_relation me está dando dolor de cabeza. esto es lo que he hecho:

blood_relation(X,Y):-ancestor(X,Y).
blood_relation(X,Y):-uncle(X,Y);brother(X,Y);sister(X,Y);(mother(Z,Y),sister(X,Z));(father(Z,Y),sister(X,Z));(father(Z,Y),brother(X,Z)).
blood_relation(X,Y):-uncle(X,Z),blood_relation(Z,Y).

y yo estoy haciendo yo creo resultados satisfactorios (tengo impresiones dobles - puedo solucionar este problema), el problema es que quiero que esta relación sea simétrica. No se trata ahora.

blood_relation(johns_father, joh):yes 
blood_relation(john,johns_father): no

so..is Hay una manera de solucionar este problema. Y necesito consulta: Todos los pares que no están en blood_relation ..

Actualización:

  

¿Qué tipo de relaciones es la primera declaración supone que satisfacer?   blood_relation (X, Y): - blood_relation (X, Y)

.

sorry..it es una mala copia / paste..it

blood_relation(X,Y):-ancestor(X,Y).

Ahora fija arriba.

aquí hay otras reglas:

father(X,Y):-parent(X,Y),male(X).  
mother(X,Y):-parent(X,Y),female(X).  
brother(X,Y):-parent(Z,X),parent(Z,Y),male(X).  
sister(X,Y):-parent(Z,X),parent(Z,Y),female(X).  
grandFather(X,Y):-parent(Z,Y),parent(X,Z),male(X).  
grandMother(X,Y):-parent(Z,Y),parent(X,Z),female(X).  
uncle(X,Y):-mother(Z,Y),brother(X,Z).  
ancestor(X,Y):-ancestor(X,Y).  
ancestor(X,Y):-parent(X,Z),ancestor(Z,Y).

El hermano de la madre está en la definición tío. Es un poco extraño. Tengo reglas que tengo que poner en práctica, y no sé cómo puedo aplicar reglas además de eso. Estoy confundido.

¿Alguna idea de cómo hacer simétrica blood_relation? Y not_blood_relation es una nueva regla. Y necesito consulta. Éste me está dando dolor de cabeza. Tal vez porque relación se escribe como basura.

Y no hay más datos. Eso es todo. Todas las reglas, y todos los hechos.

consulta .. not(blood_relation(X,Y)) no funciona, y yo realmente no sé qué. Por ejemplo consulta:

age(X,Y), Y>18,  
not(parent(X,Z)),write(X),nl,fail.

funciona bien

¿Fue útil?

Solución

Un poco parece una tarea, ¿no es así ...

Un truco que la mayoría de los principiantes de prólogo no piensan en la lista es la coincidencia de patrones. Piense en un árbol como la [a1, [[a2], [B2, [[E3], [F3]]], [c2]]] como en <tree> = [root, [<tree1>, <tree2>, ... ]]:

%Y is immediate child of X?
child(X,Y,[X|S]) :- member([Y|_],S).

%pick one tree in S and check
child(X,Y,[X|S]) :- member([Z|SS],S),child(Z,Y,[Z|SS]).

%X and Y end up with same root?
sib(X,Y,[R|T]) :- child(R,X,[R|T]), child(R,Y,[R|T]).

Creo que se puede mejorar este similares, utilizando pares como raíces, añadiendo géneros, dando nombres a las relaciones específicas de los miembros del árbol ...

Otros consejos

La solución ingenuo para hacer una simétrica predicado en particular no está tan lejos de una decente. Por el bien de la generalidad, vamos a ver una relación de amistad por lo que la gente no se tropezó en tíos y similares.

A continuación algunos datos que detalla una relación de amistad (donde, por ejemplo, los números son los identificadores de usuario y el ordenamiento particular de los argumentos provenía de que inició la amistad).

friends(1,2).
friends(5,2).
friends(7,4).

Se podría pensar inicialmente una regla como "friends(A,B) :- friends(B,A)." arreglaría las cosas bien, pero esto le lleva a la recursividad infinita porque dice prólogo que si sólo se intercambia el argumento una vez más que sólo podría funcionar. Hay un predicado llamado "@</2" que le indica si un término (incluso una variable) está antes que otras en la "orden estándar de términos". El significado técnico no es tan importante aquí, pero lo que nos importa es que durante dos términos diferentes que sólo es cierto para un pedido de ellos. Podemos usar esto para romper el bucle infinito!

Esta norma única se encargará de hacer simétrica "friend/2".

friends(A,B) :- A @< B, friends(B,A).

A medida ordenada, ya que es, hay una manera enfoque que debe tomar para grandes proyectos. Recordemos que el orden de los argumentos en mi lista de los hechos tenía algún significado real (que inició la amistad). La adición de la regla final destruyó el futuro acceso a esta información y, para otras personas que leen el código, se esconde la propiedad simétrica en una sola línea de código que es fácil pasar por alto en la cara de un bloque de datos no modificables.

condsider la solución de potencia industrial:

friended(1,2).
friended(5,2).
friended(7,4).

friends(A,B) :- friended(A,B).
friends(A,B) :- friended(B,A).

Es más voluminoso, pero lee limpiamente sin utilizar predicados oscuros y conserva la información original (que es posible que desee de nuevo algún día en una aplicación real).

-

En cuanto a la búsqueda de parejas que no tener una propiedad específica, asegúrese de incluir siempre algún predicado para proporcionar el contexto en la regla cuando se utiliza la negación a buscar individuos reales.

potential_enemies(A,B) :- user(A), user(B), \+ friends(A,B).

¿Qué tipo de relaciones es la primera declaración supone que satisfacer?

blood_relation(X,Y):-blood_relation(X,Y).

Eso no le está diciendo cualquier cosa que usted no tiene ya "sabe" y va a hacer que la recursividad dolores de cabeza. En cuanto a la respuesta 'no', es Parece que ya ha conseguido todas las respuestas de la consulta que se va a conseguir, y el intérprete es sólo que le dice que no hay nada más.

Usted realmente debe publicar más datos, y la definición de tío / 2, y hay una razón por la que no estés a juego hermano de una madre, sólo su hermana? Tienes un montón de otras cuestiones para trabajar en: -).

Por todo lo que no es una relación de sangre, intente esto:

not_blood_relation(X, Y) :- blood_relation(X, Y), !, fail.
not_blood_relation(X, Y).

Y preguntarse por qué funciona!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top