4

I have a somewhat complex predicate with four arguments that need to work when both the first and last arguments are ground/not ground, not ground/ground or ground/ground, and the second and third arguments are ground.

i.e. predicate(A,B,C,D).

I can't provide my actual code since it is part of an assignment.

I have it mostly working, but am receiving instantiation errors when A is not ground, but D is. However, I have singled out a line of code that is causing issues. When I change the goal order of the predicate, it works when D is ground and A is not, but in doing so, it no longer works for when A is ground and D is not. I'm not sure there is a way around this.

Is there a way to use both lines of code so that if the A is ground for instance it will use the first line, but if A is not ground, it will use the second, and ignore the first? And vice versa.

repeat
  • 18,496
  • 4
  • 54
  • 166
Wolff
  • 1,051
  • 3
  • 18
  • 31

1 Answers1

4

You can do that, but, almost invariably, you will break the declarative semantics of your programs if you do that.

Consider a simple example to see how such a non-monotonic and extra-logical predicate already breaks basic assumptions and typical declarative properties of well-known predicates, like commutativity of conjunction:

?- ground(X), X = a.
false.

But, if we simply exchange the goals by commutativity of conjunction, we get a different answer:

?- X = a, ground(X).
X = a.

For this reason, such meta-logical predicates are best avoided, especially if you are just beginning to learn the language.

Instead, better stay in the pure and monotonic subset of Prolog. Use constraints like dif/2 and CLP(FD) to make your programs usable in all directions, increasing generality and ease of understanding.

See , and for more information.

mat
  • 40,498
  • 3
  • 51
  • 78