N-Queens problem using answer set programming - answer-set-programming

trying to learn answer set programming and decided to give the n-queens problem a go. This is what I have so far:-
% Queens are placed on an n x n chess board.
% Each queens must not attack each other.
% Represent the chess board squares.
square(1..n, 1..n).
% Place a Queen on one chess square.
queen(1..n).
5 { on(Q, X, Y) : queen(Q), square(X, Y) } 5.
:- queen(Q), on(Q, X, Y), on(Q, X', Y'), X != X', Y != Y'.
% Make sure each square only has one queen.
:- queen(Q), queen(Q'), on(Q, X, Y), on(Q', X, Y), Q != Q'.
% A Queen attacks another if both are on the same vertical, horizontal or diagonal.
:- on(Q, X, Y), on(Q', X, Y'), Q != Q', Y != Y'.
:- on(Q, X, Y), on(Q', X', Y), Q != Q', X != X'.
:- on(Q, X, Y), on(Q', X', Y'), Q != Q', |X-X'| = |Y-Y'|.
I am using clingo with the command - clingo n-queens.lp --const n=5 --models 2. The output that I get is:-
As you can see, despite stating that the queens should not be in the same column or row, the output contains some. What is wrong with the program?
Do you guys have some tips in general for getting better at ASP? I feel like I always get stuck when trying to describe the knowledge in ASP syntax.

There are 2 issues with your program:
5 { on(Q, X, Y) : queen(Q), square(X, Y) } 5.
should be
n { on(Q, X, Y) : queen(Q), square(X, Y) } n.
if you want it for anything else than n=5 and
:- queen(Q), on(Q, X, Y), on(Q, X', Y'), X != X', Y != Y'.
should be
:- queen(Q), on(Q, X, Y), on(Q, X', Y'), X != X'.
:- queen(Q), on(Q, X, Y), on(Q, X', Y'), Y != Y'.
This is because you want to write :- ..., X != X' OR Y != Y' and not :- ..., X != X' AND Y != Y' - causing this constraint to take effect only if both values differ.
For the output I added also:
#show on/3.
tested with the online version of clingo (added #const n=5. to the code):
clingo version 5.5.0
Reading from stdin
Solving...
Answer: 1
on(2,3,3) on(4,4,5) on(5,2,1) on(1,1,4) on(3,5,2)
SATISFIABLE
Please note that the online version provides a very neat example of n-queens.
Your program works but there is room for improvement. If you want to implement efficient code, a first hint would be to reduce the size of the ground logic program. This can be done - for example - by reducing the arity of predicates.

Related

The Hilbert epsilon operator

Why you can use the Hilbert epsilon operator in a method and in a function, but not in a "function method"?
method choose<T>(s:set<T>) returns (x:T)
requires s != {}
{
var z :| z in s;
return z;
}
function choose'<T>(s:set<T>):T
// function method choose'<T>(s:set<T>):T // Activate this line and comment the previous line to see the error
requires s != {}
{
var z :| z in s;
z
}
In order for the Hilbert epsilon operator, also known in Dafny as the let-such-that expression,
var z :| P; E
to be compilable, the constraint P must determine z uniquely. In your case, the constraint P is z in s, which does not determine z uniquely except for singleton sets.
If s were of type set<int>, you can (inefficiently) live up to this requirement by changing your choose' function to:
function method choose'<T>(s:set<int>):int
requires s != {}
{
var z :| z in s && forall y :: y in s ==> z <= y;
z
}
Almost. You need to convince Dafny there is such a z. You can do that in a lemma. Here's a probably-longer-than-necessary-but-the-first-thing-I-got-working lemma that does that. Note that the lemma also uses the Hilbert operator, but in a statement context, so the uniqueness requirement does not apply.
function method choose'<T>(s:set<int>):int
requires s != {}
{
HasMinimum(s);
var z :| z in s && forall y :: y in s ==> z <= y;
z
}
lemma HasMinimum(s: set<int>)
requires s != {}
ensures exists z :: z in s && forall y :: y in s ==> z <= y
{
var z :| z in s;
if s == {z} {
// the mimimum of a singleton set is its only element
} else if forall y :: y in s ==> z <= y {
// we happened to pick the minimum of s
} else {
// s-{z} is a smaller, nonempty set and it has a minimum
var s' := s - {z};
HasMinimum(s');
var z' :| z' in s' && forall y :: y in s' ==> z' <= y;
// the minimum of s' is the same as the miminum of s
forall y | y in s
ensures z' <= y
{
if
case y in s' =>
assert z' <= y; // because z' in minimum in s'
case y == z =>
var k :| k in s && k < z; // because z is not minimum in s
assert k in s'; // because k != z
}
}
}
Unfortunately, the type of your s is not set<int>. I don't know how to get a unique value from a general set. :(
For information about why the uniqueness requirement is important in compiled expressions see this paper.
Rustan

Dimension of arrays do not agree

I have to solve this matrix equation in MATLAB
(A + p(1)E) V(1) = B , and find V(1)
B dimension is 280 x 4
A dimension is 280 x 280
E dimension is 280 x 280
p dimension is 15 x 1
I have tried this
L=inv((A + p(1)*E));
V(1) = B*L;
but i get this error
Error using ==> mtimes
Inner matrix dimensions must agree.
Do you know what goes wrong, or an other way to solve it?
Thanks in advance
As the error says, you can only multiply two matrices which have same size of the inner dimension, eg:
Q(l x m) * P(m x n) = R(l x n)
So when you try to multiply
B(280 x 4) * L(280 x 280)
The error comes up.
Obviously this is because the algebra is also not ok, which should be
V(280 x 4) = L(280 x 280) * B(280 x 4)
Since the product of matrices is not commutative and the correct algebra here is
(A + p E) V = B
L V = B
V = L^-1 B

HIVE : Not in clause

Is there any way to execute the following Sql query in HiveQL?
select * from my_table
where (a,b,c) not in (x,y,z)
where a,b,c correspond respectively to x,y,z
Thanks:)
You'll have to break these down to separate conditions:
SELECT *
FROM my_table
WHERE a != x AND b != y AND c != z
Is this what you intend?
where a <> x or b <> y or c <> z
Or this?
where a not in (x, y, z) and
b not in (x, y, z) and
c not in (x, y, z)
Or some other variation?

Isabelle: degree of polynomial multiplied with constant

I am working with the library HOL/Library/Polynomial.thy.
A simple property didn't work. E.g., the degree of 2x *2 is equal to the degree of 2x-
How can I prove the lemmas (i.e., remove "sorry"):
lemma mylemma:
fixes y :: "('a::comm_ring_1 poly)" and x :: "('a::comm_ring_1)"
shows "1 = 1" (* dummy *)
proof-
have "⋀ x. degree [: x :] = 0" by simp
from this have "⋀ x y. degree (y * [: x :] ) = degree y" sorry
(* different notation: *)
from this have "⋀ x y. degree (y * (CONST pCons x 0)) = degree y" sorry
.
From Manuel's answer, the solution I was looking for:
have 1: "⋀ x. degree [: x :] = 0" by simp
{
fix y :: "('a::comm_ring_1 poly)" and x :: "('a::comm_ring_1)"
from 1 have "degree (y * [: x :]) ≤ degree y"
by (metis Nat.add_0_right degree_mult_le)
}
There are a number of issues here.
First of all, the statement you are trying to show simply does not hold for all x. If x = 0 and y is nonconstant, e.g. y = [:0,1:], you have
degree (y * [: x :]) = degree 0 = 0 ≠ 1 = degree y
The obvious way to fix this is to assume x ≠ 0.
However, this is not sufficient either, since you only assumed 'a to be a commutative ring. However, in a commutative ring, in general, you can have zero divisors. Consider the commutative ring ℤ/4ℤ. Let x = 2 and y = [:0,2:].
Then y * [:x:] = [:0,4:], but 4 = 0 in ℤ/4ℤ. Therefore y * [:x:] = 0, and therefore, again,
degree (y * [: x :]) = degree 0 = 0 ≠ 1 = degree y
So, what you really need is one of the following two:
the assumption x ≠ 0 and 'a::idom instead of 'a::comm_ring. idom stands for “integral domain” and, that is simply a commutative ring with a 1 and without zero divisors
more generally, the assumption that x is not a zero divisor
even more generally, the assumption that x * y ≠ 0 or, equivalently, x times the leading coefficient of y is not 0
Also, the usage of ⋀ in Isar proofs is somewhat problematic at times. The “proper“ Isar way of doing this would be:
fix x :: "'a::idom" and y :: "'a poly"
assume "x ≠ 0"
hence "degree (y * [:x:]) = degree y" by simp
The relevant lemmas are degree_mult_eq and degree_smult_eq, you will see that they require the coefficient type to be an idom. This works for the first case I described above, the other two will require some more manual reasoning, I think.
EDIT: just a small hint: you can find theorems like this by typing
find_theorems "degree (_ * _)"
If you try to apply the degree_mult_eq it shows to your situation (with comm_ring), you will find that it fails, even though the terms seem to match. If that is the case, it is usually a type issue, so you can write something like
from [[show_sorts]] degree_mult_eq
to see what the types and sorts required by the lemma are, and it says idom.

Symbolic Equation Solver, Saving Symbolic Equations [duplicate]

From here, I'm trying to solve a symbolic system of equations like this
syms x y z;
[x, y, z] = solve('z = 4*x', 'x = y', 'z = x^2 + y^2')
x =
0
2
y =
0
2
z =
0
8
except that my equations are generated at different points in the m-file and with random coefficients. My question is how can I accomplish the following...
// Generate the first equation.
n = *random number generated here*;
E1 = (z == n*x + 2*n); // <--- How to save this symbolic equation to use in "solve(...)" later?
// Other work, generate other eqs.
...
// Solve system of eqs.
[x, y, z] = solve( E1 , E2, E3) // What/How to call/use the previously saved symbolic equations.
Thanks for the help!
EDIT
Updated to better explain objective.
Use sprintf if you want to keep the randomly generated value of n for later use with solve:
n = *random number generated here*;
E1 = (z == n*x + 2*n);
Eq1 = sprintf('z == %f*x + 2*%f',n,n);
You can play with the parameters on %f to see how much precision you want to include.