Try to learn minizinc but after going through examples, may I just confirm that I actually have to write some procedural language if I want to get multiple output or there is a more "natural to minizinc" way to get it.
For example, suppose I want to have all distinct digits add up to 3 the answers should be 0+3 1+2 2+1 3+0 ...
My mininzinc here:
% how to generate more than one result meeting the constraints
int: n=3;
var 0..9: a;
var 0..9: b;
include "alldifferent.mzn";
constraint all_different([a, b]);
constraint a + b = n;
solve satisfy;
output [
"a + b = n \t\n",
show(a), " + ",
show(b), " = ",
show(n)];
produce only 3+0. How to get to the other answers? Thanks for any advice in advance.
I looked at a post for minizinc 1.6 and it seemed to say left out the output statement would produce all the output (Easy way to print full solution (all decision variables) in minizinc). It does not work. Only one is output.
First of all, the default is to print all variables and their values for a solution, not all solutions.
Use the option -a to get all solutions. mzn-gecode --help to see all options. In your case mzn-gecode -a test.mzn which gives:
a + b = n
3 + 0 = 3
----------
a + b = n
0 + 3 = 3
----------
a + b = n
2 + 1 = 3
----------
a + b = n
1 + 2 = 3
----------
==========
Under configuration there is an option to change the default from printing the first solution after satisfaction. Change it to user-defined-behaviour: print all solutions ... You can have output statement, btw, as well.
Related
I have a table
t: flip `S`V ! ((`$"|A|B|"; `$"|B|C|D|"; `$"|B|"); 1 2 3)
and some dicts
t1: 4 10 15 20 ! 1 2 3 5;
t2: 4 10 15 20 ! 0.5 2 4 5;
Now I need to add a column with values on the the substrings in S and the function below (which is a bit pseudocode because I am stuck here).
f:{[s;v];
if[`A in "|" vs string s; t:t1;];
else if[`B in "|" vs string s; t:t2;];
k: asc key t;
:t k k binr v;
}
problems are that s and v are passed in as full column vectors when I do something like
update l:f[S,V] from t;
How can I make this an operation that works by row?
How can I make this a vectorized function?
Thanks
You will want to use the each-both adverb to apply a function over two columns by row.
In your case:
update l:f'[S;V] from t;
To help with your pseudocode function, you might want to use $, the if-else operator, e.g.
f:{[s;v]
t:$["A"in ls:"|"vs string s;t1;"B"in ls;t2;()!()];
k:asc key t;
:t k k binr v;
};
You've not mentioned a final else clause in your pseudocode but $ expects one hence the empty dictionary at the end.
Also note that in your table the columns S and V have been cast to a symbol. vs expects a string to split so I've had to use the stringoperation - this could be removed if you are able to redefine your original table.
Hope this helps!
I'm reading about Property based testing using Scala language. In this slide, they present this concept: For proving function a+b is true. we just only to prove those statements are true on random data:
a + b = b + a
a + 0 = a
a + 1 + 1 = a + 2
My question is: Which methodologies for checking that our test cases are enough, and can cover all cases on different data. For example on previous example, how can we sure that after our three properties run correctly, we can sure that our implementation is right.
First of all, I assume, you have a typo in #3, it's supposed to be + rather than *.
To answer your question, you most certainly can not be sure that your implementation is right if you prove these three properties. Consider this implementation for instance, that satisfies all three properties, but is definitely wrong:
def wrongPlus(a: Int, b: Int) = if(a < 3 || b <3) b a+b else 0
To definitively prove the (integer) addition, you need to have an independent implementation of next integer. Then, by definition:
1. a + 0 = a
2. a + next(b) = next(a + b)
If these properties hold for any a and b and some operation +, then + is indeed the addition.
Can I convert a symbol that is a product of products into an array of products?
I tried to do something like this:
syms A B C D;
D = A*B*C;
factor(D);
but it doesn't factor it out (mostly because that isn't what factor is designed to do).
ans =
A*B*C
I need it to work if A B or C is replaced with any arbitrarily complicated parenthesized function, and it would be nice to do it without knowing what variables are in the function.
For example (all variables are symbolic):
D = x*(x-1)*(cos(z) + n);
factoring_function(D);
should be:
[x, x-1, (cos(z) + n)]
It seems like a string parsing problem, but I'm not confident that I can convert back to symbolic variables afterwards (also, string parsing in matlab sounds really tedious).
Thank you!
Use regexp on the string to split based on *:
>> str = 'x*(x-1)*(cos(z) + n)';
>> factors_str = regexp(str, '\*', 'split')
factors_str =
'x' '(x-1)' '(cos(z) + n)'
The result factor_str is a cell array of strings. To convert to a cell array of sym objects, use
N = numel(factors_str);
factors = cell(1,N); %// each cell will hold a sym factor
for n = 1:N
factors{n} = sym(factors_str{n});
end
I ended up writing the code to do this in python using sympy. I think I'm going to port the matlab code over to python because it is a more preferred language for me. I'm not claiming this is fast, but it serves my purposes.
# Factors a sum of products function that is first order with respect to all symbolic variables
# into a reduced form using products of sums whenever possible.
# #params orig_exp A symbolic expression to be simplified
# #params depth Used to control indenting for printing
# #params verbose Whether to print or not
def factored(orig_exp, depth = 0, verbose = False):
# Prevents sympy from doing any additional factoring
exp = expand(orig_exp)
if verbose: tabs = '\t'*depth
terms = []
# Break up the added terms
while(exp != 0):
my_atoms = symvar(exp)
if verbose:
print tabs,"The expression is",exp
print tabs,my_atoms, len(my_atoms)
# There is nothing to sort out, only one term left
if len(my_atoms) <= 1:
terms.append((exp, 1))
break
(c,v) = collect_terms(exp, my_atoms[0])
# Makes sure it doesn't factor anything extra out
exp = expand(c[1])
if verbose:
print tabs, "Collecting", my_atoms[0], "terms."
print tabs,'Seperated terms with ',v[0], ', (',c[0],')'
# Factor the leftovers and recombine
c[0] = factored(c[0], depth + 1)
terms.append((v[0], c[0]))
# Combines trivial terms whenever possible
i=0
def termParser(thing): return str(thing[1])
terms = sorted(terms, key = termParser)
while i<len(terms)-1:
if equals(terms[i][1], terms[i+1][1]):
terms[i] = (terms[i][0]+terms[i+1][0], terms[i][1])
del terms[i+1]
else:
i += 1
recombine = sum([terms[i][0]*terms[i][1] for i in range(len(terms))])
return simplify(recombine, ratio = 1)
When I add a line to the middle of a file, all following lines have their number incremented.
Is there a utility that generates the list of equivalent line numbers between two files?
The output would be something like:
1 1
2 2
3 4 (line added)
4 5
One can probably create such utility by using dynamic programming in a way similar to the diff algorithm. Seems useful, hasn't already been done?
I found out it is pretty easy to do with python's difflib:
import difflib
def seq_equivs(s1, s2):
equiv = []
s = difflib.SequenceMatcher(a=s1, b=s2)
for m in s.get_matching_blocks():
if m[2] == 0:
break
for n in range(1, 1+m[2]):
equiv.append((m[0]+n, m[1]+n))
return equiv
Example usage:
f1 = open('file1.txt').read().split('\n')
f2 = open('file2.txt').read().split('\n')
for equivs in seq_equivs(f1, f2):
print('%d %d' % equivs)
So I want to simplify z:=a+I*b; Im(z) where a, b are real variables So I try:
s:= 1+2*I
Im(s) // outputs 2
z:=a+I*b
Im(z) // outputs Im(a+I*b)
So I wonder is it any how possible to simplify Im(z) so to get b as output (here we look at general case meaning z could be any complex expression from real values (like a, b, c etc and complex I))?
You didn't tell Maple that a and b were real, so the simplification doesn't work because it doesn't necessarily hold. One way to get what you want is by using the assume command to let it know:
> s:=1+2*I;
s := 1 + 2 I
> Im(s);
2
> z:=a+I*b;
z := a + b I
> Im(z);
Im(a + b I)
> assume(a,real);
> assume(b,real);
> z;
a~ + b~ I
> Im(z);
b~
The evalc command works by considering unknowns as being real.
z:=a+I*b:
Im(z);
Im(a + I b)
evalc( Im(z) );
b
See its help-page, ?evalc.