I am continuing my journey from here.
I am trying to learn ASP and working on a project like this:
Find the sequence s = (s1, s2, ..., sn) with the following properties:
- s is a permutation of the set {0, 1, ..., n-1};
- the sequence v = (|s2-s1|, |s3-s2|, ..., |sn-sn-1|) is a permutation of the set {1, 2, ..., n-1};
Solve this problem for n = 11.
I feel like I've made progress, but I am stuck now.
Here is the code I have:
% Define a sequence s = (s1, s2, ..., sn), n = 11, values between 0 and 10.
{s(N) : N=0..10}.
% Each number 0-10 has to occur exactly once.
1 { in(N) : s(N) } 1 :- N=0..10.
% I want s to be a permutation of {0,1,2,...,10} - how?
% ???
% Define a sequence v = (...), values between 0 and 10.
{v(M) : M=1..10}.
% Define the calculation of absolute differences between two adjacent elements of s.
diff(X, Y, D) :- v(X), v(Y), D = |X-Y|.
% Define a set of such differences.
abs_diff(D) :- diff(_, _, D).
% Each number 1-10 has to occur exactly once in that sequence.
1 { in_v(A) : v(A) } 1 :- A=1..10.
% v is a set of those differences.
v(X) :- abs_diff(X).
% Display results.
#show s/1.
#show v/1.
The program runs, but returns the wrong output: v(1) v(2) v(3) v(4) v(5) v(6) v(7) v(8) v(9) v(10) v(0) s(0) s(1) s(2) s(3) s(4) s(5) s(6) s(7) s(8) s(9) s(10)
What I feel like I am missing is defining 's' to be a permutation of the set {0,1,2,...,10} instead of always being that set. But how can I do that?
I have tried the following solutions:
- Does not run properly.
% Define the input set
set(0..10).
% Define the permutation predicate
perm([]).
perm([X|T]) :-
set(X),
select(X, Set, Rest),
perm(T),
Set = [X|Rest].
% Define the select predicate to choose an element from the set
select(X, [X|T], T).
select(X, [H|T], [H|T1]) :-
select(X, T, T1).
-:5:6-7: error: syntax error, unexpected [, expecting ) or ;
-:6:6-7: error: syntax error, unexpected [, expecting ) or ;
-:13:11-12: error: syntax error, unexpected [
-:14:11-12: error: syntax error, unexpected [
- Output still wrong.
1 { permute(I,D) : I=1..10, D=1..11 } 1 :-
dif(1,1), dif(10,11),
{ permute(I,D) : I=1..10, D=1..11 } = 11,
permutation(D, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]).
- Output still wrong.
#const n=11.
1 { s(X,Y) : Y=0..n-1 } 1 :- X=1..n.
:- s(X,Y), s(Z,Y), X!=Z.
:- s(X,Y), s(X,Z), Y!=Z.
Any help is appreciated.
Welcome to asp.
So by reading through you code I guess it is best to show you some example code. To start of: in answer set programming, you work with sets of atoms. Therefore if you have a permutation you not only require the data but also its position. A choice rule
{c(0..5)}.says that every possiblec(N)may or may not be in the model. Try it from the webpage but choose enumerate all as mode: https://potassco.org/clingo/run/Ok, how to encode a permutation? By defining predicates with arity 2: one for the position, one for the content
Usually one of the two rules sufficies, but I like to write out both :)
Also please note you can reuse variable symbols in different rules.
Since
vis also a permutation, you can define it just as such but for a different domain. Also please notevlacks one element in comparison tosNow you need to link
vandstogheter. Best choice is using constraints, since those do not add new atoms to the programm but can only reduce the number of potential answer sets. So what do we need? For any positionPyou need to know the fitting value in the permutationsandvand have them fullfill your equation.Please note that the order of the atoms in the constraint does not matter and the reading is one of many interpretations of this rule.
And thats it. You can test your code on the clingo website.