transitividad transitivas transitiva simetricas simetrica resueltos relaciones relacion reflexivas reflexiva propiedades matriz matematicas las gramática equivalencia ejemplos discretas clases prolog transitive-closure

prolog - transitivas - Cómo expresar una relación transitiva



relaciones reflexivas simetricas y transitivas (1)

El _639 es una variable anónima _639 . Tus "hechos" tienen variables en lugar de átomos. Por ejemplo:

proj(A). % This has a variable A and means "any A is a project"

Entonces si pregunto:

:- proj(X). X = _blah % anonymous variable: anything is a project!

Necesitas átomos:

proj(a). proj(b).

Que resulta en la consulta:

:- proj(X). X = a ; X = b

Si usted tiene:

ref(a,b). ref(b,c).

Entonces, la forma más simple en Prolog para expresar una propiedad transitiva es declarando una regla (o lo que se conoce como un predicado en Prolog):

ref(A,C) :- ref(A,B), ref(B,C).

Esto dice que, ref(A,C) es verdadero si ref(A,B) es verdadero, Y ref(B,C) es verdadero. . Ejecutando la consulta:

:- ref(a,c). true ; Out of stack

O:

:- ref(a,X). X = b ; X = c ; Out of stack

Entonces suena lógico pero tiene un problema: puede entrar en un ciclo debido a la autorreferencia. Una forma sencilla de evitar esto es hacer que el nombre de la regla sea diferente al hecho:

refx(A, B) :- ref(A, B). refx(A, C) :- ref(A, B), refx(B, C).

Ahora si consulto:

:- refx(a, b). true ; no :- refx(a, c). yes :- refx(a, X). X = b ; X = c yes

Etc.

Todavía hay casos en que esto podría tener problemas de terminación, sin embargo, si los hechos contienen relaciones reflexivas o conmutativas. Por ejemplo:

ref(a,b). ref(b,a). ref(b,c).

En este caso, una consulta a refx(a, b) produce:

| ?- refx(a, b). true ? ; true ? ; true ? ; ...

Como señala @ lambda.xy.x, esto podría resolverse rastreando dónde hemos estado y evitando repetir "visitas":

refx(X, Y) :- refx(X, Y, []). refx(X, Y, A) :- ref(X, Y), /+ memberchk((X, Y), A). % Make sure we haven''t visited this case refx(X, Y, A) :- ref(X, Z), /+ memberchk((X, Z), A), % Make sure we haven''t visited this case refx(Z, Y, [(X,Z)|A]).

Ahora terminamos con refx(a,b) y lo conseguimos una vez:

| ?- refx(a,b). true ? ; no | ?-

Y refx(X, Y) produce todas las soluciones (aunque, algunas repeticiones debido a tener éxito más de una vez):

| ?- refx(X, Y). X = a Y = b ? ; X = b Y = a ? ; X = b Y = c ? ; X = a Y = a ? ; X = a Y = c ? ; X = b Y = b ? ; X = b Y = c ? ; (2 ms) no

Quiero expresar una relación transitiva. Si A hace referencia B y B hace referencia a C, A se refiere a C. Tengo esto:

proj(A). proj(B). proj(C). ref(A,B). ref(B,C).

Cuando consulto usando proj(A) obtengo:

[46]? -proj (A).
A = _639

¿Qué significa "_639"? Esperaba un sí o un no y obtuve esa extrañeza. Necesito agregar una regla para decir:

ref(A,C). y obtener SÍ. Idealmente, si es posible, me gustaría mostrar cómo se produjo esta relación: (A => B => C).