minizinc sitting-friends-at-a-table-far-from-furius ones - constraints

1.we have cycling table
2.a man must be sit next to a woman and a woman next to a man
3. guests must share hobbies (at least one common between their hobbies)
4. there are couples of furious guests. they must not sit near to next to each other
5. nobody of list o furious guests must sit at start(seat 1) or end (seat N)
-pR is the number of furious couples
my model:
int :N;
set of int: GUESTS = 1..N;
set of int: POSITIONS = 1..N;
array[GUESTS] of 1..2 : gender;
array[GUESTS] of set of int: hobbies;
enum PAIR = {first,second};
int : pR;
set of int: LIST = 1..pR;
array[LIST,PAIR] of GUESTS : furious;
array[POSITIONS] of var GUESTS : guest_at;
array[POSITIONS] of var 1..2: table_gender;
constraint forall(i in 1..length(table_gender)-1)(
table_gender[i]!=table_gender[i+1]
/\
table_gender[1]!=table_gender[length(table_gender)]
)
;
include "alldifferent.mzn";
constraint alldifferent(guest_at);
constraint forall(i in 2..N-1)(card(hobbies[guest_at[i+1]] intersect hobbies[guest_at[i]]) >0);
constraint card(hobbies[guest_at[N]] intersect hobbies[guest_at[1]]) >0;
constraint forall(i in 2..N-1,l in LIST, p in PAIR)(if guest_at[i]=furious[i,first] then guest_at[i+1]!=furious[i,second] /\ guest_at[i-1]!=furious[i,second] else true endif);
constraint forall(l in LIST, p in PAIR)(guest_at[1]!=furious[l,p] /\ guest_at[N]!=furious[l,p]);
solve satisfy;
output
["guest_at = \(guest_at);"]
++ ["\ntable_gender = \(table_gender); \n" ]
++ ["Furious Placement\n"]
++ [show_int(4,furious[i,j]) | i in LIST, j in PAIR] ++["\n"]
++ [if fix(guest_at[p]) = furious[i,j] then show_int(4,p) else "" endif | i in LIST, j in PAIR, p in POSITIONS]
;
my model's bugs:
C:/Users/�������/Documents/������/����������/Gala/gala.mzn:36:
in call 'forall'
in array comprehension expression
with i = 4
with l = 3
with p = 1
in if-then-else expression
in binary '=' operator expression
in array access
WARNING: Further warnings have been suppressed.

This constraint, where there errors are referring to, contains a couple of strange things:
constraint
forall(i in 2..N-1,l in LIST, p in PAIR) (
if guest_at[i]=furious[i,first] then
guest_at[i+1]!=furious[i,second] /\
guest_at[i-1]!=furious[i,second]
else
true
endif
);
1) The second and third loop parameters l in List and p in PAIR is never used, so they are meaningless.
2) The main reason for the warning is that the furious matrix is just two rows, but in the loop variable i goes from 2 to 16. The error (array access out of bounds) indicates that when i is larger than 2 it's out of bound of the furious matrix.

Related

How to check if a number is palindrome in Clean

I am solving this homework of clean programming language;
The problem is we have a number of five digits and we want to check whether it's an odd palindrome or not.
I am stuck at the stage of dividing the number to five separate digits and perform a comparison with the original number, for the palindrome check. With Clean I can't loop over the number and check if it remains the same from the both sides, so I am looking for an alternative solution (Some mathematical operations).
Code block:
isOddPalindrome :: Int -> Bool
isOddPalindrome a
| isFive a <> 5 = abort("The number should be exactly five digits...")
| (/*==> Here should be the palindrome check <==*/) && (a rem 2 <> 0) = True
| otherwise = False
isFive :: Int -> Int
isFive n
| n / 10 == 0 = 1
= 1 + isFive(n / 10)
My idea is to take the number, append it's digits one by one to an empty list, then perform the reverse method on the list and check if it's the same number or not (Palindrome)
Your answer above doesn't have a stopping condition so it will result in stack overflow.
You could try this
numToList :: Int -> [Int]
numToList n
| n < 10 = [n]
= numToList (n/10) ++ [n rem 10]
Start = numToList 12345
and then like you mentioned in the answer, you can reverse it with the 'reverse' function and check if they are equal.
After hours of trying to figure out how to recursively add the digits of our number to an empty list, I did the following:
sepDigits :: Int [Int] -> [Int]
sepDigits n x = sepDigits (n/10) [n rem 10 : x]
Now I can easily check whether the reverse is equal to the initial list :) then the number is palindrome.

constraint dependents in array of classes

How can I constraint 2 variables in an array of classes, when there is a dependent between different items of the array?
class X;
rand bit en;
rand int idx;
constraint cnst1{
idx inside {[0:9]};
}
endclass
class Y;
rand X arr_x[100];
constraint cnst2{
???
}
endclass
I want to create cnst2 that will guarantee that:
each idx optional value (0-9) will be set for at least one of the arr_x[i].idx .
for all of the arr_x[i] that have the same value of idx, at least 1 will have en set to 1.
for example:
let's say that only the following have idx == 9:
arr_x[0].idx == 9;
arr_x[13].idx == 9;
arr_x[44].idx == 9;
arr_x[75].idx == 9;
arr_x[81].idx == 9;
arr_x[93].idx == 9;
need to guarantee that:
arr_x[0].en | arr_x[13].en | arr_x[44].en | arr_x[75].en | arr_x[81].en | arr_x[93].en == 1;
and so on for every idx value;
You want the or array reduction method. Also create a helper array so you can iterate from 0-9. This constraint reads: if at least one element has the value 0-9, then one of those elements has to have en set.
bit iterator[10];
constraint cnst2{
foreach(iterator[i])
arr_x.or(x) with (i ==x.idx) -> // needed if idx will not have every value 0-9
arr_x.or(y) with (i == y.idx && y.en);
}
See sections 18.5.8.2 Array reduction iterative constraints and 7.12.3 Array reduction methods in the IEEE 1800-2017 SystemVerilog LRM.

Pattern Matching SML?

Can someone please explain the: "description of g"? How can f1 takes unit and returns an int & the rest i'm confused about too!!
(* Description of g:
* g takes f1: unit -> int, f2: string -> int and p: pattern, and returns
* an int. f1 and f2 are used to specify what number to be returned for
* each Wildcard and Variable in p respectively. The return value is the
* sum of all those numbers for all the patterns wrapped in p.
*)
datatype pattern = Wildcard
| Variable of string
| UnitP
| ConstP of int
| TupleP of pattern list
| ConstructorP of string * pattern
datatype valu = Const of int
| Unit
| Tuple of valu list
| Constructor of string * valu
fun g f1 f2 p =
let
val r = g f1 f2
in
case p of
Wildcard => f1 ()
| Variable x => f2 x
| TupleP ps => List.foldl (fn (p,i) => (r p) + i) 0 ps
| ConstructorP (_,p) => r p
| _ => 0
end
Wildcard matches everything and produces the empty list of bindings.
Variable s matches any value v and produces the one-element list holding (s,v).
UnitP matches only Unit and produces the empty list of bindings.
ConstP 17 matches only Const 17 and produces the empty list of bindings (and similarly for other integers).
TupleP ps matches a value of the form Tuple vs if ps and vs have the same length and for all i, the i-th element of ps matches the i-th element of vs. The list of bindings produced is all the lists from the nested pattern matches appended together.
ConstructorP(s1,p) matches Constructor(s2,v) if s1 and s2 are the same string (you can compare them with =) and p matches v. The list of bindings produced is the list from the nested pattern match. We call the strings s1 and s2 the constructor name.
Nothing else matches.
Can someone please explain the: "description of g"? How can f1 takes unit and returns an int & the rest i'm confused about too!!
The function g has type (unit → int) → (string → int) → pattern → int, so it takes three (curried) parameters of which two are functions and one is a pattern.
The parameters f1 and f2 must either be deterministic functions that always return the same constant, or functions with side-effects that can return an arbitrary integer / string, respectively, determined by external sources.
Since the comment speaks of "what number to be returned for each Wildcard and Variable", it sounds more likely that the f1 should return different numbers at different times (and I'm not sure what number refers to in the case of f2!). One definition might be this:
local
val counter = ref 0
in
fun uniqueInt () = !counter before counter := !counter + 1
fun uniqueString () = "s" ^ Int.toString (uniqueInt ())
end
Although this is just a guess. This definition only works up to Int.maxInt.
The comment describes g's return value as
[...] the sum of all those numbers for all the patterns wrapped in p.
Since the numbers are not ascribed any meaning, it doesn't seem like g serves any practical purpose but to compare the output of an arbitrarily given set of f1 and f2 against an arbitrary test that isn't given.
Catch-all patterns are often bad:
...
| _ => 0
Nothing else matches.
The reason is that if you extend pattern with additional types of patterns, the compiler will not notify you of a missing pattern in the function g; the catch-all will erroneously imply meaning for cases that are possibly yet undefined.

Standard ML: Size of binary tree computed incorrectly?

My book has the following function which calculates the number of non-leaf nodes in a binary tree:
fun size Empty = 0
| size(Node(t_1, _, t_2)) = size t_1 + size t_2 + 1;
Suppose I want to calculate all nodes in a binary tree. How would I modify this function to do so?
Here's what I was thinking:
fun size Empty = 0
| size(Node(Empty, _, Empty)) = 1
| size(Node(t_1, _, t_2)) = size t_1 + size t_2 + 1;
Does this look right?
Thanks,
bclayman
Both of the implementations that you provided are actually the same. The second case of your second implementation is a special case of you your third pattern. For your first implementation, size(Node(Empty,1,Empty)) will recurse one the left subtree, returning 0, recurse on the right subtree, which returns 0, and then adds 1, yielding the result 1. In fact, if you switch the order of the second and third case, the compiler will tell you that it is redundant:
test.sml:3.5-5.38 Error: match redundant
Empty => ...
Node (t_1,_,t_2) => ...
--> Node (Empty,_,Empty) => ...
Matt is correct that your two functions are functionally the same -- both of which return a count of all nodes in the tree. I didn't notice this at first since I took it at face value that your first function counted nonleaf nodes and then noticed that your Node(Empty,_,Empty) pattern is the correct pattern of a leaf (if a leaf is defined as a node with no non-empty children). But -- this means that the function in the book doesn't just count nonleaf (parents) nodes. If you do want a function which just counts parent nodes, there is a use for your pattern after all:
fun parents Empty = 0
| parents(Node(Empty, _, Empty)) = 0
| parents(Node(t_1, _, t_2)) = parents t_1 + parents t_2 + 1;
If your application of trees is one in which heavy use is made of the parent node vs. leaf node distinction, you could (at the cost of making some of your function definitions more involved) ditch the Node constructor in favor of separate Parent and Leaf constructors. Something like:
datatype 'a tree = Empty | Leaf of 'a | Parent of 'a tree * 'a * 'a tree;
Then you can write functions like
fun countLeaves Empty = 0
| countLeaves (Leaf _) = 1
| countLeaves (Parent(t1,_,t2)) = countLeaves t1 + countLeaves t2;
So e.g.
- val t = Parent(Parent(Leaf "2", "*", Leaf "3"), "+", Leaf "4");
- countLeaves t;
val it = 3 : int

How to use predicate exactly in MiniZinc

New MiniZinc user here ... I'm having a problem understanding the syntax of the counting constraint:
predicate exactly(int: n, array[int] of var int: x, int: v)
"Requires exactly n variables in x to take the value v."
I want to make sure each column in my 10r x 30c array has at least one each of 1,2 and 3, with the remaining 7 rows equal to zero.
If i declare my array as
array[1..10,1..30] of var 0..3: s;
how can I use predicate exactly to populate it as I need? Thanks!
Well, the "exactly" constraint is not so useful here since you want at least one occurrence of 1, 2, and 3. It's better to use for example the count function:
include "globals.mzn";
array[1..10,1..30] of var 0..3: s;
solve satisfy;
constraint
forall(j in 1..30) (
forall(c in 1..3) (
count([s[i,j] | i in 1..10],c) >= 1
)
)
;
output [
if j = 1 then "\n" else " " endif ++
show(s[i,j])
| i in 1..10, j in 1..30
];
You don't have do to anything about 0 since the domain is 0..3 and all values that are not 1, 2, or 3 must be 0.
Another constraint is "at_least", see https://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html .
If you don't have read the MiniZinc tutorial (https://www.minizinc.org/downloads/doc-latest/minizinc-tute.pdf), I strongly advice you to. The tutorial teaches you how to think Constraint Programming and - of course - MiniZinc.

Resources