Reputation: 566
I'm trying to generate some Kakuros, generate not solve.
I have all rules to generate it, but the firsts results are senseless, those are like squares.
Now I want to skip some branches, 15000 for example, to see the kakuro generated at that point.
I have tried with an Auxiliary Variable, but when it fails, the Kakuro Generator start again.
Upvotes: 1
Views: 617
Reputation: 1915
You can keep a dynamic counter-like predicate in the knowledge base that gets increased every time the main predicate is executed. The value of the counter is changed with assert
and retract
, i.e., it is not a variable within your main predicate but a globally stored value.
Within your main predicate, if you add the condition that the counter should be higher than some skip value, then you force backtracking over the actual rules for a specified number of iterations.
As an example, consider the built-in predicate permutation/2
which computes permutations of a list (note: tested using SWI-Prolog, other interpreters have different built-in predicates). Example output:
?- permutation([1,2,3,4,5],L).
L = [1, 2, 3, 4, 5] ;
L = [1, 2, 3, 5, 4] ;
L = [1, 2, 4, 3, 5] ;
L = [1, 2, 4, 5, 3] ;
L = [1, 2, 5, 3, 4] ;
L = [1, 2, 5, 4, 3] ;
If you want to skip the first 5 iterations in your query, you can use the following code:
:- dynamic iteration_nr/1.
iteration_nr(0).
get_permutations(L1,L2,Skip) :-
permutation(L1,L2),
iteration_nr(N),
N2 is N+1,
retract(iteration_nr(N)),
asserta(iteration_nr(N2)),
Skip < N2. % force backtracking here if counter < Skip
Example output:
?- get_permutations([1,2,3,4,5],L2,5).
L2 = [1, 2, 5, 4, 3] ;
L2 = [1, 3, 2, 4, 5] ;
L2 = [1, 3, 2, 5, 4]
Note that asserta
is used here (i.e., assert at the start) instead of plain assert
, which is deprecated. Note also that the counter will keep the value, so when you run this a second time in the same session the results will be different. To reset the counter you can use a separate initialization predicate, for example:
init_and_get_permutations(L1,L2,Skip) :-
retractall(iteration_nr(_)),
asserta(iteration_nr(0)),
get_permutations(L1,L2,Skip).
Further note: the use of assert
and retract
is not really considered 'clean' Prolog programming, because it is procedural and changes the knowledge base. However, for some applications it can be useful.
Upvotes: 1