Prologue: missing function?

Any programmer with some experience with Prolog knows the benefits of using unary notation for numbers. For example, if we represent a number as a list of 1 "(" 4 "is a list of" [1,1,1,1] ", etc.), we can define:

unary_succ(X,[1|X]). 

The following requests are expected:

 ?- X=[1,1],unary_succ(X,Y). X = [1, 1], Y = [1, 1, 1]. ?- unary_succ(X,Y),X=[1,1]. X = [1, 1], Y = [1, 1, 1]. ?- unary_succ(X,Y),Y=[1,1]. X = [1], Y = [1, 1]. 

Thus, the unary_succ (X, Y) operator β€œbinds” X and Y in such a way that if, after the fact is specified, one of these variables is bound to the value, the other does.

However, this behavior is not possible if we use the internal representation of a number:

 ?- X=2,succ(X,Y). X = 2, Y = 3. ?- succ(X,Y),X=2. ERROR: succ/2: Arguments are not sufficiently instantiated ?- succ(X,Y),Y=2. ERROR: succ/2: Arguments are not sufficiently instantiated 

In my opinion, it will be very useful for previous statements and similar cases to do what was expected. That is, we need to bind the two variables in such a way that when one of them is tied to a value, the other fulfills the rule established earlier.

My questions:

a) some easy way to do this in Prolog.

b) if this is not possible, any other programming language that supports this function?

Any comments are welcome.

Thanks to everyone.

* Adding me *

Another example:

 user_id(john,1234). user_id(tom,5678). 

and requests:

 X=john,user_id(X,Y). user_id(X,Y),X=john 

which are currently being addressed through backtracking.

+5
source share
2 answers

This topic is called coroutining and should be solved in a fairly general way - afaik - requires an extension of the basic Prolog calculation model. Fortunately, most prologs have this extension ... So, try using SWISH to create your own "reactive" extension:

 my_succ(X, Y) :- when((nonvar(X);nonvar(Y)), succ(X, Y)). 

change not completely to a point, but Jan posted on the SWI-Prolog mailing list a simple example of an accompanying application:

 ?- freeze(X, writeln(X)), findall(X, between(1,3,X), Xs). 1 2 3 Xs = [1, 2, 3], freeze(X, writeln(X)). 
+3
source

The problem you are describing exists as long as the responses of the Prolog system are limited to (syntactic) responses to the answers. In your example, the goal of succ(X, Y) would require an infinite number of answers to describe the entire set of solutions. For this reason, instantiation_error is instantiation_error instead.

To solve this problem, we need to expand the answers. Therefore, answers not only include substitution of answers, but also a more detailed way of describing some sets.

library(clpfd) , suggesting restrictions on Z (and most noticeably finite areas).

 ?- use_module(library(clpfd)). ?- Y #= X+1. X+1#=Y. 

Note that such solvers are not very strong for the general case:

 ?- Y #= X+1, X #= Y+1. Y+1#=X, X+1#=Y. 

You can expect the system to fail, however it gives an answer that basically repeated the request. At least the answer is not wrong, because it simply states: yes, there is a solution on the condition that is relevant (which is not, it looks like a fine print in insurance contracts or guarantee certificates).

when/2 also known as coroutining and in many cases is weaker than what you get with clpfd . But in some cases, it is stronger for some clpfd implementations. Consider dif/2 , which can be expressed as when(?=(X,Y), X \== Y) and

 | ?- dif(X, Y), X = Y. no 

... whereas (in SICStus)

 | ?- X #\= Y, X #= Y. Y #= X, Y #\= X, Y in inf..sup, X in inf..sup ? ; no 

library(clpq) offers a solver that is stronger in many situations, but does not have whole specific limitations, such as mod/2 . In many situations, it is still interesting to use, as here in SICStus:

 | ?- use_module(library(clpq)). yes | ?- {Y=X+1}. {X = -1+Y} ? yes | ?- {Y=X+1}, {X=Y+1}. no 
+4
source

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


All Articles