write unificacion sentencia reglas manejo listas fuente conocimiento codigo clausulas if-statement prolog conditional

if statement - unificacion - Prolog, lista de construcción con cláusulas condicionales



unificacion prolog (4)

Necesito hacer esta tarea con Prolog (SWI-flavor) y no puedo entender algunas cosas.

Por ejemplo, si quiero iterar a través de una lista y agregar sus elementos a otra, pero SÓLO si cumplen ciertas condiciones, ¿cómo lo haré? Puedo agregarlos todos, o ninguno, pero si agrego una cláusula que comprueba esta condición, la recursividad completa resulta ser "falsa". Entiendo por qué es esto, pero no tengo idea de cómo solucionarlo. Básicamente lo que quiero es:

goal(Stuff) :- do_something(X), only_do_this_if_something(Y), always_do_this(Z).

Actualmente, si only_do_this_if_something(Y) falla, también always_do_this(Z) no ocurre ya que el objetivo completo se vuelve falso ...


Compruebe el siguiente patrón de programación, que se usa bastante en Prolog:

  • Itera a través de la lista, un elemento a la vez
  • Establecer un caso base para la recursión
  • En una cláusula, verifique si se aplican las condiciones y haga algo, luego continúe con la recursión
  • En la siguiente cláusula omita el elemento y continúe con la recursión

Tienes que usar el corte (!) Para prohibir el rastreo posterior o verificar explícitamente que la condición no se aplique en la última cláusula.

Tenga en cuenta que dijo que quería tener una lista de salida con los elementos para los que se aplicó ''algo'' (que no es lo que escribió en su código) ...

Aplicando este patrón a su problema se vería algo como esto:

myRecursion([], []). % This is the base case myRecursion([Item|Tail], [Item|NTail]):- something_applies(...), do_something(...), only_do_this_if_something(...), always_do_this(...). myRecursion(Tail, NTail). myRecursion([Item|Tail], NTail):- not(something_applies(...)), do_something(...), always_do_this(...), myRecursion(Tail, NTail).


Si entiendo correctamente, entonces lo que necesita es un predicado como include/3 :

include(:Goal, +List1, ?List2) Filter elements for which Goal succeeds. True if List2 contains those elements Xi of List1 for which call(Goal, Xi) succeeds.

Ejemplo de uso:

?- include(number, [a(b), 2, _, 1.2, C, ''1''], L). L = [2, 1.2].

Ahora su tarea se convierte en "cómo implementar include/3 ". Una vez que haya implementado su versión de include/3 , puede verificar si coincide con la versión de SWI mirando su código fuente: listing(include) .


prueba el predicado ignorar / 1:

goal(Stuff) :- do_something(X) ignore(only_do_this_if_something(Y)), always_do_this(Z).

ignorar / 1 llama al único argumento y tiene éxito siempre que falle o no:

ignore(X) :- X, !. ignore(_).


puedes usar la estructura if:

<condition> -> (do_something) ; (do_something else)

en este caso:

goal(Stuff):- do_something(X), if_something(Y)-> do_this(Y) ; true, always_do_this(Z).

o simplemente escribe dos cláusulas como:

goal(Stuff):- do_something(X), conditional_stuff(Y), always_do_this(Z). conditional_stuff(Y):- condition(Y), do_this(Y). conditional_stuff(_).