Get a value from residual goals - prolog

If I have X #> 3. Prolog will give the residual goal X in 4..sup.. How can I assign X one of the possible values from 4 to sup? Any random value will suffice.

In SWI-Prolog,you can get random value assign with using secret option random_value(Seed).
see this:How does `random_variable `random_value` work in SWI-Prolog's labeling/2?
:- use_module(library(clpfd)).
random_labeling_test(A):-
A in 1..5,
labeling([random_value(332)],[A]).
?- random_labeling_test(A).
A = 5 ;
A = 1 ;
A = 2 ;
A = 4 ;
A = 3.
332 is meaningless.Set random seed into here.current milliseconds is often used .
I'm not sure this option is safe.
But in your case,this cannot work because upper bounds is infinite.It is reasonable.
In ECLiPSe, labeling variable selection and assigning value selection is completly controllable with using indomain and delete.
see this:http://eclipseclp.org/doc/tutorial/tutorial088.html

One naive way to solve this is to use a predicate like this:
enumeration(Z) :-
length(_, N),
enumeration_(N, Z).
enumeration_(N, N).
enumeration_(N0, N) :- N #= -N0.
You can now solve your task as follows:
?- X #> 3, enumeration(X).
X = 4 ;
X = 5 ;
X = 6 ;
X = 7 ;
X = 8 .
Pros:
a quite simple solution
portable to different Prolog systems.
Con:
potentially quite slow.
Example:
?- X #> 2^100, enumeration(X).
[waiting...]
To make this more efficient, you need to take into account the actual domains of variables.
There are at least two ways to do this:
(a) Use your solver's reflection predicates
Reflection predicates let you reason about the actual domains of variables by making them available as Prolog terms.
For example, where available, you can use fd_inf/2 to obtain the infimum of a constrained variable's domain:
?- X #> 3, fd_inf(X, Inf).
Inf = 4,
X in 4..sup.
You can use this as a starting point for the enumeration. I leave this as a challenge.
See your Prolog system's manual for more information about its reflection predicates.
(b) Inspect the residual goals
Alternatively, you can inspect the residual goals as Prolog terms. This is also a reflection mechanism, though one that only needs a single predicate for all kinds of different constraint solvers.
For example, where available, you can use copy_term/3 to obtain the residual goals as a list of Prolog goals:
?- X #> 3, copy_term(X, X, Gs).
Gs = [clpfd:(X in 4..sup)],
X in 4..sup.
From these goals, it is again straight-forward to deduce the infimum of X's domain.
Note that the top-level can use this same mechanism to actually produce the residual goals.

Related

Does it matter what is unification terms sequence?

Lets consider I have two terms T1 and T2. I unified two terms and got result.
My question is: If I change places of terms and unify terms T2 and T1 - whether result will be the same or different?
I tried to change terms and got the same result. But in theory I can read: in Prolog sequence is important.
So how do you think - is the result the same or different and why?
A difference that shows simply by replacing X = Y by Y = X is highly unlikely.
As long as you consider syntactic unification (using the occurs-check) or rational tree unification, the only differences might be some minimal performance differences.
More visible differences are surfacing when going beyond these well defined relations:
when mixing both, unification may not terminate. I can only give you somewhat related examples in SWI and Scryer:
?- X = s(X), unify_with_occurs_check(X, s(X)).
X = s(X).
?- unify_with_occurs_check(X, s(X)), X = s(X).
false.
Above, commutativity of goals is broken. But then, we are mixing two incompatible theories with one another. So, we can't really complain.
?- Y = s(Y), unify_with_occurs_check(X-X,s(X)-Y).
false.
?- Y = s(Y), unify_with_occurs_check(X-X,Y-s(X)).
Y = s(Y), X = s(Y) % Scryer
| Y = X, X = s(X). % SWI
And here we just exchange the order of arguments. It is general intuition that exchanging (consistently) arguments of a functor should not produce a difference, but helas, here again the incompatible mix is the culprit.
when constraints and side-effects are involved. Still, I fail to produce such a case just replacing X = Y by Y = X.

Prolog nth1 anonymous variables

I have a List with Integers and anonymous variables and I try to find the index of a special values. Problem is as soon I'm using nth1/3 to find the indices Prolog assigns values to the anonymous variables and therefore I find way too indices.
Example:
List = [1,\_,1], where I want as result X = 1, X = 3 from nth1(X,List,1), but as stated before I get X = 1, X = 2, X = 3.
There is a somewhat problematic issue hidden in your requirements: They violate an important declarative property called monotonicity. By this we mean that adding constraints can at most make the solution more specific, never more general.
For example, with the solution you posted, we get:
?- list_el_index([_], 1, N).
false.
Now I add a constraint by imposing an additional requirement on the hitherto free anonymous variable:
?- Var = 1, list_el_index([Var], 1, N).
Var = 1,
N = 0 .
I mean: Come on! We have added a constraint, and as a result get more solutions than before? Such a result is unfortunate and prevents us from reasoning in a logical way about this program.
The program also fails us in other respects. For example, let us ask: Which solutions are there at all?
?- list_el_index(Ls, El, I).
nontermination
Ideally, we would like the program to generate solutions in such cases! This generality is one of the foremost attractions of logic programming, and distinguishes it from more low-level paradigms.
One way to solve such issues is to symbolically distinguish the different kinds of elements that appear in your list.
For example, let us use:
u for an unknown value.
i(I) for an integer I.
With this new representation, your solution becomes:
list_el_index([i(I)|_], I, 0).
list_el_index([_|Tail], Element, Index) :-
list_el_index(Tail, Element, Index0),
Index #= Index0+1.
I have also taken the liberty to replace (is)/2 by (#=)/2, to advertise and stick to more general integer arithmetic that lets us more freely reorder the goals, if necessary. Depending on your Prolog implementation, you may have to import a library to benefit from (#=)/2.
With this representation, your initial case becomes:
?- list_el_index([i(1),u,i(1)], 1, Index).
Index = 0 ;
Index = 2 ;
false.
This works as desired!
Importantly, we can use the predicate also more generally, namely to generate possible answers:
?- list_el_index(Ls, El, I).
Ls = [i(El)|_2994],
I = 0 ;
Ls = [_2992, i(El)|_3000],
I = 1 ;
Ls = [_2992, _2998, i(El)|_3006],
I = 2 ;
Ls = [_2992, _2998, _3004, i(El)|_3012],
I = 3 .
Due to the program's monotonicity, we can fairly enumerate solutions by iterative deepening:
?- length(Ls, _), list_el_index(Ls, El, I).
Ls = [i(El)],
I = 0 ;
Ls = [i(El), _4812],
I = 0 ;
Ls = [_4806, i(El)],
I = 1 ;
Ls = [i(El), _4812, _4818],
I = 0 ;
etc.
This has become possible by using a representation that lets us distinguish the cases by pattern matching. Consider using this approach to make your programs usable in all directions, and to make logical reasoning applicable. It is quite easy to apply by using the appropriate wrapper or constant, and greatly increases the generality of your programs.
This works :
- L = [1,_,1], nth1(X, L, Y), ground(Y), Y= 1.
L = [1,_310914,1],
X = Y, Y = 1 ;
L = [1,_310914,1],
X = 3,
Y = 1.
Thanks to lurkers hint, I came up with this solution.
list_el_index([El1|_], El2, 0) :-
El1 == El2.
list_el_index([_|Tail], Element, Index) :-
list_el_index(Tail, Element, Index1),
Index is Index1+1.

sudoku solver in prolog without clpfd

I have an AI project in which I should make a sudoku solver in Prolog but without using the clpfd package. How should I write the code and is there any way to print whenever a variable gets a value?
Without clpfd, you have to write a classic generate-and-test search. The nice thing about clpfd is that the constraints limit the search space. You can emulate this without using clpfd though. Let's simplify the task a bit so I can illustrate. How can you find X and Y values that solve both of these equations: X + Y = 10, 2*X + Y - 1 = 15?
First, encode your two equations:
eq1(X,Y) :- 10 is X + Y.
eq2(X,Y) :- 15 is 2*X + Y - 1.
Now create your search space in a solver predicate:
solution(X, Y) :-
between(1, 10, X), between(1, 10, Y),
eq1(X,Y),
eq2(X,Y).
Now you can run it and see:
?- solution(X,Y).
X = 6,
Y = 4 ;
false.
This is less efficient than it would be with clpfd because clpfd would notice things about the equations that would help it constrain the search space:
?- [library(clpfd)].
true.
?- X + Y #= 10, 2*X + Y - 1 #= 15.
2*X+Y#=16,
X+Y#=10.
?- X + Y #= 10, 2*X + Y - 1 #= 15, X in 1..10.
X = 6,
Y = 4.
See, it has already figured out that there is only one solution and I didn't have to constrain Y at all. That's very impressive! But you can still use Prolog without clpfd, it's just worse. :) In this example, we probably tried all 10x10=100 possible combinations to find this one solution. Less efficient. But not impossible.
So, what are the constraints you have to figure out for sudoku? Probably something like this:
unique(Row) :- sort(Row, Sorted), length(Row, Length), length(Sorted, Length).
all_digits(Row) :- forall(between(1,9,X), memberchk(X, Row)).
And so forth.
Edit: Combinatorial complexity estimation
Suppose we do a totally unprincipled search: that is, we even try obviously wrong cases like a grid of all 9s. We have 9x9=81 cells and 9 possible values (1-9). This yields 9^81 = a very large number, unlikely to be checked in your lifetime. And most of those grids are going to be fruitless permutations.
Suppose you constrain your search so that each row is a permutation of 1-9. There are 9! permutations of 1-9; with nine of those, you can multiply that outcome by nine, so there should be 9!^9. This is still awful! clpfd is probably able to further winnow this down by combining the 3x3 grid constraints; I'm not sure how I would go about doing that manually, other than in a semi-procedural way, choosing a 3x3 grid permutation and then passing each 3x1 row of that on to the next 3x3 grid selection.
It's worth noting that most of the optimization in classic Prolog programs comes down to either making the generate step generate better-qualified candidates or making the test step less expensive. A more obvious implementation can still be useful for checking a more complex implementation.
Thanks to #mat for checking my math and recommending this excellent article on the combinatorial problem of Sudoku.

Counter-intuitive behavior of min_member/2

min_member(-Min, +List)
True when Min is the smallest member in the standard order of terms. Fails if List is empty.
?- min_member(3, [1,2,X]).
X = 3.
The explanation is of course that variables come before all other terms in the standard order of terms, and unification is used. However, the reported solution feels somehow wrong.
How can it be justified? How should I interpret this solution?
EDIT:
One way to prevent min_member/2 from succeeding with this solution is to change the standard library (SWI-Prolog) implementation as follows:
xmin_member(Min, [H|T]) :-
xmin_member_(T, H, Min).
xmin_member_([], Min0, Min) :-
( var(Min0), nonvar(Min)
-> fail
; Min = Min0
).
xmin_member_([H|T], Min0, Min) :-
( H #>= Min0
-> xmin_member_(T, Min0, Min)
; xmin_member_(T, H, Min)
).
The rationale behind failing instead of throwing an instantiation error (what #mat suggests in his answer, if I understood correctly) is that this is a clear question:
"Is 3 the minimum member of [1,2,X], when X is a free variable?"
and the answer to this is (to me at least) a clear "No", rather than "I can't really tell."
This is the same class of behavior as sort/2:
?- sort([A,B,C], [3,1,2]).
A = 3,
B = 1,
C = 2.
And the same tricks apply:
?- min_member(3, [1,2,A,B]).
A = 3.
?- var(B), min_member(3, [1,2,A,B]).
B = 3.
The actual source of confusion is a common problem with general Prolog code. There is no clean, generally accepted classification of the kind of purity or impurity of a Prolog predicate. In a manual, and similarly in the standard, pure and impure built-ins are happily mixed together. For this reason, things are often confused, and talking about what should be the case and what not, often leads to unfruitful discussions.
How can it be justified? How should I interpret this solution?
First, look at the "mode declaration" or "mode indicator":
min_member(-Min, +List)
In the SWI documentation, this describes the way how a programmer shall use this predicate. Thus, the first argument should be uninstantiated (and probably also unaliased within the goal), the second argument should be instantiated to a list of some sort. For all other uses you are on your own. The system assumes that you are able to check that for yourself. Are you really able to do so? I, for my part, have quite some difficulties with this. ISO has a different system which also originates in DEC10.
Further, the implementation tries to be "reasonable" for unspecified cases. In particular, it tries to be steadfast in the first argument. So the minimum is first computed independently of the value of Min. Then, the resulting value is unified with Min. This robustness against misuses comes often at a price. In this case, min_member/2 always has to visit the entire list. No matter if this is useful or not. Consider
?- length(L, 1000000), maplist(=(1),L), min_member(2, L).
Clearly, 2 is not the minimum of L. This could be detected by considering the first element of the list only. Due to the generality of the definition, the entire list has to be visited.
This way of handling output unification is similarly handled in the standard. You can spot those cases when the (otherwise) declarative description (which is the first of a built-in) explicitly refers to unification, like
8.5.4 copy_term/2
8.5.4.1 Description
copy_term(Term_1, Term_2) is true iff Term_2 unifies
with a term T which is a renamed copy (7.1.6.2) of
Term_1.
or
8.4.3 sort/2
8.4.3.1 Description
sort(List, Sorted) is true iff Sorted unifies with
the sorted list of List (7.1.6.5).
Here are those arguments (in brackets) of built-ins that can only be understood as being output arguments. Note that there are many more which effectively are output arguments, but that do not need the process of unification after some operation. Think of 8.5.2 arg/3 (3) or 8.2.1 (=)/2 (2) or (1).
8.5.4 1 copy_term/2 (2),
8.4.2 compare/3 (1),
8.4.3 sort/2 (2),
8.4.4 keysort/2 (2),
8.10.1 findall/3 (3),
8.10.2 bagof/3 (3),
8.10.3 setof/3 (3).
So much for your direct questions, there are some more fundamental problems behind:
Term order
Historically, "standard" term order1 has been defined to permit the definition of setof/3 and sort/2 about 1982. (Prior to it, as in 1978, it was not mentioned in the DEC10 manual user's guide.)
From 1982 on, term order was frequently (erm, ab-) used to implement other orders, particularly, because DEC10 did not offer higher-order predicates directly. call/N was to be invented two years later (1984) ; but needed some more decades to be generally accepted. It is for this reason that Prolog programmers have a somewhat nonchalant attitude towards sorting. Often they intend to sort terms of a certain kind, but prefer to use sort/2 for this purpose — without any additional error checking. A further reason for this was the excellent performance of sort/2 beating various "efficient" libraries in other programming languages decades later (I believe STL had a bug to this end, too). Also the complete magic in the code - I remember one variable was named Omniumgatherum - did not invite copying and modifying the code.
Term order has two problems: variables (which can be further instantiated to invalidate the current ordering) and infinite terms. Both are handled in current implementations without producing an error, but with still undefined results. Yet, programmers assume that everything will work out. Ideally, there would be comparison predicates that produce
instantiation errors for unclear cases like this suggestion. And another error for incomparable infinite terms.
Both SICStus and SWI have min_member/2, but only SICStus has min_member/3 with an additional argument to specify the order employed. So the goal
?- min_member(=<, M, Ms).
behaves more to your expectations, but only for numbers (plus arithmetic expressions).
Footnotes:
1 I quote standard, in standard term order, for this notion existed since about 1982 whereas the standard was published 1995.
Clearly min_member/2 is not a true relation:
?- min_member(X, [X,0]), X = 1.
X = 1.
yet, after simply exchanging the two goals by (highly desirable) commutativity of conjunction, we get:
?- X = 1, min_member(X, [X,0]).
false.
This is clearly quite bad, as you correctly observe.
Constraints are a declarative solution for such problems. In the case of integers, finite domain constraints are a completely declarative solution for such problems.
Without constraints, it is best to throw an instantiation error when we know too little to give a sound answer.
This is a common property of many (all?) predicates that depend on the standard order of terms, while the order between two terms can change after unification. Baseline is the conjunction below, which cannot be reverted either:
?- X #< 2, X = 3.
X = 3.
Most predicates using a -Value annotation for an argument say that pred(Value) is the same
as pred(Var), Value = Var. Here is another example:
?- sort([2,X], [3,2]).
X = 3.
These predicates only represent clean relations if the input is ground. It is too much to demand the input to be ground though because they can be meaningfully used with variables, as long as the user is aware that s/he should not further instantiate any of the ordered terms. In that sense, I disagree with #mat. I do agree that constraints can surely make some of these relations sound.
This is how min_member/2 is implemented:
min_member(Min, [H|T]) :-
min_member_(T, H, Min).
min_member_([], Min, Min).
min_member_([H|T], Min0, Min) :-
( H #>= Min0
-> min_member_(T, Min0, Min)
; min_member_(T, H, Min)
).
So it seems that min_member/2 actually tries to unify Min (the first argument) with the smallest element in List in the standard order of terms.
I hope I am not off-topic with this third answer. I did not edit one of the previous two as I think it's a totally different idea. I was wondering if this undesired behaviour:
?- min_member(X, [A, B]), A = 3, B = 2.
X = A, A = 3,
B = 2.
can be avoided if some conditions can be postponed for the moment when A and B get instantiated.
promise_relation(Rel_2, X, Y):-
call(Rel_2, X, Y),
when(ground(X), call(Rel_2, X, Y)),
when(ground(Y), call(Rel_2, X, Y)).
min_member_1(Min, Lst):-
member(Min, Lst),
maplist(promise_relation(#=<, Min), Lst).
What I want from min_member_1(?Min, ?Lst) is to expresses a relation that says Min will always be lower (in the standard order of terms) than any of the elements in Lst.
?- min_member_1(X, L), L = [_,2,3,4], X = 1.
X = 1,
L = [1, 2, 3, 4] .
If variables get instantiated at a later time, the order in which they get bound becomes important as a comparison between a free variable and an instantiated one might be made.
?- min_member_1(X, [A,B,C]), B is 3, C is 4, A is 1.
X = A, A = 1,
B = 3,
C = 4 ;
false.
?- min_member_1(X, [A,B,C]), A is 1, B is 3, C is 4.
false.
But this can be avoided by unifying all of them in the same goal:
?- min_member_1(X, [A,B,C]), [A, B, C] = [1, 3, 4].
X = A, A = 1,
B = 3,
C = 4 ;
false.
Versions
If the comparisons are intended only for instantiated variables, promise_relation/3 can be changed to check the relation only when both variables get instantiated:
promise_relation(Rel_2, X, Y):-
when((ground(X), ground(Y)), call(Rel_2, X, Y)).
A simple test:
?- L = [_, _, _, _], min_member_1(X, L), L = [3,4,1,2].
L = [3, 4, 1, 2],
X = 1 ;
false.
! Edits were made to improve the initial post thanks to false's comments and suggestions.
I have an observation regarding your xmin_member implementation. It fails on this query:
?- xmin_member(1, [X, 2, 3]).
false.
I tried to include the case when the list might include free variables. So, I came up with this:
ymin_member(Min, Lst):-
member(Min, Lst),
maplist(#=<(Min), Lst).
Of course it's worse in terms of efficiency, but it works on that case:
?- ymin_member(1, [X, 2, 3]).
X = 1 ;
false.
?- ymin_member(X, [X, 2, 3]).
true ;
X = 2 ;
false.

Prolog: Random Labeling

I have a program written in Sicstus Prolog using constraints.
My goal is to use labeling/2 and some other method to obtain a random instantiation of my variables.
Example:
X #> 2, Y #= 2*X, Z #<10
If I use
List = [X,Y,Z],
labeling([], List)
The first result obtained will be X = Y = Z = 0. How do you think is the best way to return a random set of values for X, Y and Z?
I do not know much about the labeling options in recent SICStus versions, but with library(clpfd) of SWI-Prolog, there are the options random_variable(Seed) and random_value(Seed), you can use them for example with labeling([random_variable(10),random_value(10)], List). Maybe you can get the authors of SICStus to integrate similar options?
In sicstus, this is done with a custom selection of variables / values.
In your case, just do:
labeling([value(mySelValores)], List)
mySelValores(Var, _Rest, BB, BB1) :-
fd_set(Var, Set),
select_best_value(Set, Value),
(
first_bound(BB, BB1), Var #= Value
;
later_bound(BB, BB1), Var #\= Value
).
select_best_value(Set, BestValue):-
fdset_to_list(Set, Lista),
length(Lista, Len),
random(0, Len, RandomIndex),
nth0(RandomIndex, Lista, BestValue).
See value(Enum) in https://sicstus.sics.se/sicstus/docs/4.0.4/html/sicstus/Enumeration-Predicates.html.
Hope it helps ;)
you can use
all_different([X,Y,Z]) in order to get different values
however, working with random seed in Sicstus could be tricky and you may need to define a function to change the seed or start the random function again.
check below
www.sics.se/sicstus/docs/3.7.1/html/sicstus_23.html
I have opted in Jekejeke Prolog, for a new predicate random_labeling/1 in connection
with CLP(FD) that takes implicitly the random number generator from the knowledge base
that can be accessed and modified via the sys_random Prolog flag.
Jekejeke Prolog 3, Runtime Library 1.3.4
(c) 1985-2019, XLOG Technologies GmbH, Switzerland
?- use_module(library(finite/clpfd)).
% 20 consults and 0 unloads in 944 ms.
Yes
?- use_module(library(basic/random)).
% 0 consults and 0 unloads in 0 ms.
Yes
?- random_new(111,R), set_prolog_flag(sys_random,R),
X in 0..5, Y #= X*X, random_label([X,Y]),
write(X-Y), nl, fail; true.
4-16
3-9
5-25
1-1
2-4
0-0
Yes
?- random_new(111,R), set_prolog_flag(sys_random,R),
X in 0..5, Y #= X*X, random_label([X,Y]),
write(X-Y), nl, fail; true.
4-16
3-9
5-25
1-1
2-4
0-0
I am planning a further predicate random_labeling/2. But it would not take a seed, but instead a Java java.util.Random instance. This is more versatile than a seed. But I guess changing the API to labeling/2 and some options would be the best way to go.
Edit 29.12.2018: I will now take notes, since I guess its a good idea
to adopt indomain/2, currently I have implemented random_indomain/1,
and from this implemented random_label/1. See also here:
indomain/2 from ECLiPSe Prolog
random: Try the enumeration in a random order. On backtracking,
the previously tested value is removed. This method uses random/1 to
create random numbers, use seed/1 before to make results reproducible.
http://eclipseclp.org/doc/bips/lib/gfd_search/indomain-2.html

Resources