Julia: Evaluate expressions from a dictionary - julia

I have a list of expressions, f.x
"a1 || a4"
"a3 && a5
and a dictionary with the truth values of these
a1 -> true
a2 -> false
I need to evaluate expressions from the list, with the true/false values from the dictionary
Any ideas how this can be achieved easily? Any help is greatly appreciated

I feel like there might be a more elegant solution but this will certainly get the job done.
truths = Dict("a1" => true, "a2" => false)
expressions = ["a1 || a4", "a1 && a2"]
for (key, value) in truths
info("evaluating: '$key = $value'")
eval(parse("$key = $value"))
end
for exp in expressions
info("$exp => $(eval(parse(exp)))")
end

What is f.x? What do you mean by a list? In future, please give working code, not code snippets like this.
In Julia you almost certainly do not want to store Julia code like a1 || a4 in strings, but rather as Julia expressions (which is what parse of a string actually gives):
ex = [:(a1 || a4), :(a3 && a5)]
Secondly, you probably don't want to use variables with names like this, but rather an array:
a = bitrand(5) # 5 random bits
a[1] # gives true
Then you would use
ex = [:(a[1] || a[4]), :(a[3] && [a[5])]
and you can just do
map(eval, ex)
which evaluates each expression in the vector.
If you think that using a[1] instead of a1 is too much typing, you can walk the syntax tree and replace a_i with a[i]. Or, if you have the strings, just use the replace function on the string:
replace("hello a3 a34", "a3", "a[3]")
(so be careful!)

Related

Using invalid character "²" for squared. Extend Julia syntax with custom operators

In my equations we have many expressions with a^2, and so on. I would like to map "²" to ^2, to obtain something like that:
julia> a² == a^2
true
The above is not however a legal code in Julia. Any idea on how could I implement it ?
Here is a sample macro #hoo that does what you requested in a simplified scenario (since the code is long I will start with usage).
julia> x=5
5
julia> #hoo 3x² + 4x³
575
julia> #macroexpand #hoo 2x³+3x²
:(2 * Main.x ^ 3 + 3 * Main.x ^ 2)
Now, let us see the macro code:
const charsdict=Dict(Symbol.(split("¹²³⁴⁵⁶⁷⁸⁹","")) .=> 1:9)
const charsre = Regex("[$(join(String.(keys(charsdict))))]")
function proc_expr(e::Expr)
for i=1:length(e.args)
el = e.args[i]
typeof(el) == Expr && proc_expr(el)
if typeof(el) == Symbol
mm = match(charsre, String(el))
if mm != nothing
a1 = Symbol(String(el)[1:(mm.offset-1)])
a2 = charsdict[Symbol(mm.match)]
e.args[i] = :($a1^$a2)
end
end
end
end
macro hoo(expr)
typeof(expr) != Expr && return expr
proc_expr(expr)
expr
end
Of course it would be quite easy to expand this concept into "pure-math" library for Julia.
I don't think that there is any reasonable way of doing this.
When parsing your input, Julia makes no real difference between the unicode character ² and any other characters you might use in a variable name. Attempting to make this into an operator would be similar to trying to make the suffix square into an operator
julia> asquare == a^2
The a and the ² are not parsed as two separate things, just like the a and the square in asquare would not be.
a^2, on the other hand, is parsed as three separate things. This is because ^ is not a valid character for a variable name and it is therefore parsed as an operator instead.

Is it possible to overload functions in Scilab?

I would like to know how to overload a function in scilab. It doesn't seem to be as simple as in C++. For example,
function [A1,B1,np1]=pivota_parcial(A,B,n,k,np)
.......//this is just an example// the code doesn't really matter
endfunction
//has less input/output variables//operates differently
function [A1,np1]=pivota_parcial(A,n,k,np)
.......//this is just an example// the code doesn't really matter
endfunction
thanks
Beginner in scilab ....
You can accomplish something like that by combining varargin, varargout and argn() when you implement your function. Take a look at the following example:
function varargout = pivota_parcial(varargin)
[lhs,rhs] = argn();
//first check number of inputs or outputs
//lhs: left-hand side (number of outputs)
//rhs: right-hand side (number of inputs)
if rhs == 4 then
A = varargin(1); B = 0;
n = varargin(2); k = varargin(3);
np = varargin(4);
elseif rhs == 5 then
A = varargin(1); B = varargin(2);
n = varargin(3); k = varargin(4);
np = varargin(5);
else
error("Input error message");
end
//computation goes on and it may depend on (rhs) and (lhs)
//for the sake of running this code, let's just do:
A1 = A;
B1 = B;
np1 = n;
//output
varargout = list(A1,B1,np1);
endfunction
First, you use argn() to check how many arguments are passed to the function. Then, you rename them the way you need, doing A = varargin(1) and so on. Notice that B, which is not an input in the case of 4 inputs, is now set to a constant. Maybe you actually need a value for it anyways, maybe not.
After everything is said and done, you need to set your output, and here comes the part in which using only varargout may not satisfy your need. If you use the last line the way it is, varargout = list(A1,B1,np1), you can actually call the function with 0 and up to 3 outputs, but they will be provided in the same sequence as they appear in the list(), like this:
pivota_parcial(A,B,n,k,np);: will run and the first output A1 will be delivered, but it won't be stored in any variable.
[x] = pivota_parcial(A,B,n,k,np);: x will be A1.
[x,y] = pivota_parcial(A,B,n,k,np);: x will be A1 and y will be B1.
[x,y,z] = pivota_parcial(A,B,n,k,np);: x will be A1, y will be B1, z will be np1.
If you specifically need to change the order of the output, you'll need to do the same thing you did with your inputs: check the number of outputs and use that to define varargout for each case. Basically, you'll have to change the last line by something like the following:
if lhs == 2 then
varargout = list(A1,np1);
elseif lhs == 3 then
varargout = list(A1,B1,np1);
else
error("Output error message");
end
Note that even by doing this, the ability to call this functions with 0 and up to 2 or 3 outputs is retained.

Convert Dict to DataFrame in Julia

Suppose I have a Dict defined as follows:
x = Dict{AbstractString,Array{Integer,1}}("A" => [1,2,3], "B" => [4,5,6])
I want to convert this to a DataFrame object (from the DataFrames module). Constructing a DataFrame has a similar syntax to constructing a dictionary. For example, the above dictionary could be manually constructed as a data frame as follows:
DataFrame(A = [1,2,3], B = [4,5,6])
I haven't found a direct way to get from a dictionary to a data frame but I figured one could exploit the syntactic similarity and write a macro to do this. The following doesn't work at all but it illustrates the approach I had in mind:
macro dict_to_df(x)
typeof(eval(x)) <: Dict || throw(ArgumentError("Expected Dict"))
return quote
DataFrame(
for k in keys(eval(x))
#eval ($k) = $(eval(x)[$k])
end
)
end
end
I also tried writing this as a function, which does work when all dictionary values have the same length:
function dict_to_df(x::Dict)
s = "DataFrame("
for k in keys(x)
v = x[k]
if typeof(v) <: AbstractString
v = string('"', v, '"')
end
s *= "$(k) = $(v),"
end
s = chop(s) * ")"
return eval(parse(s))
end
Is there a better, faster, or more idiomatic approach to this?
Another method could be
DataFrame(Any[values(x)...],Symbol[map(symbol,keys(x))...])
It was a bit tricky to get the types in order to access the right constructor. To get a list of the constructors for DataFrames I used methods(DataFrame).
The DataFrame(a=[1,2,3]) way of creating a DataFrame uses keyword arguments. To use splatting (...) for keyword arguments the keys need to be symbols. In the example x has strings, but these can be converted to symbols. In code, this is:
DataFrame(;[Symbol(k)=>v for (k,v) in x]...)
Finally, things would be cleaner if x had originally been with symbols. Then the code would go:
x = Dict{Symbol,Array{Integer,1}}(:A => [1,2,3], :B => [4,5,6])
df = DataFrame(;x...)

Rewrite recursive BNF rule with iteration

Look at the following recursive BNF rule
(1) X = Xa | b
This produces sentences like
X = b
X = ba
X = baa
X = baaa
...
This can be written as
(2) X = b a*
where the right hand side is not recursive
Now take a look at the following recursive BNF rule
(3) X = { X } | b
This produces sentences like
X = b
X = {b}
X = {{b}}
X = {{{b}}}
...
Is there some way to rewrite rule (3) in a non recursive way, analogous as we did when we rewrote rule (1) to rule (2).
Observe that X = {* b }* is no good since the parenthesis need to be balanced.
I do not know if the question above is possible to answer. The reason for the question above was that I wanted to avoid infinite loop in my parser (written in Java). One way was to insure that the BNF rules are not recursive, hence my question. But another way is to use the recursive rule, but avoid the infinite loop inside my (Java) program. Turns out that you can avoid loops by lazy instantiation.
For instance look at the following rules:
expression = term ('+' term)*;
term = factor ('*' factor)*;
factor = '(' expression ')' | Num;
expression() calls term(), which calls factor(), which calls expression(), thus we can end up with infinite loop. To avoid that we can use lazy instantiation, so instead of writing something like:
public Parser expression() {
expression = new ...
return expression;
}
we instead write:
public Parser expression() {
if (expression == null) {
expression = new ...
}
return expression;
}
Observe that you must declare expression as an instance variable to get this to work.

Putting equality constraint in z3

I am using z3's python API to solve see if a set of constraint is satisfiable or not.
I have the conditions as string and I want to directly pass them to z3 whenever possible, just to save processing time of transcoding it.
If the constraint is an assignment like a = b what is the best way to enter it.
I want something like
str1 = "a = b"
a = BitVec('a', 3)
b = BitVec('b', 3)
s = Solver()
s.push()
s.add(str1)
This program gives error as "True, False or Z3 Boolean expression expected"
Please let me know the best way to do it.
You need to pass Z3 expressions to the majority of the API functions (like Solver.add(expr)), not strings. For your example (z3py link: http://rise4fun.com/Z3Py/iu0 ):
str1 = "a = b"
a = BitVec('a', 3)
b = BitVec('b', 3)
constraint1 = a == b # sets constraint1 to be the z3 expression a == b
s = Solver()
s.push()
# s.add(str1) # error: 'True, False or Z3 Boolean expression expected'
s.add(constraint1)
print constraint1
If you want to pass strings encoded in infix notation (like "a = b"), you should be able to use Python's eval, although this may not work with full generality, so you may have to write a parser, and you cannot use eval on rise4fun due to the sanitizer:
constraint2 = eval(str1)
Here's some more details on using eval: z3python: converting string to expression
If you have strings encoded in the SMT-LIB standard (which uses prefix notation, e.g., "(= a b)"), you can use the parse_smt2_string API function. Here's an example continuing from the above:
cstr1 = "(assert (= a b))"
ds = { 'a' : a, 'b' : b }
constraint3 = parse_smt2_string(cstr1, decls=ds)
print constraint3
prove(constraint1 == constraint3)
Here's the API documentation for parse_smt2_string: http://research.microsoft.com/en-us/um/redmond/projects/z3/z3.html#-parse_smt2_string
See also this related question and answer on using infix for output of Z3 expressions: how to convert z3 expression to infix expression?

Resources