How to join the two Options<Vec<String>> - join

case 1.
v1 = None
v2 = Some(vec[..])
result = Some(vec[..])
case 2.
v1 = Some(vec[..])
v2 = None
result = Some(vec[..])
case 3.
v1 = Some(vec[..])
v2 = Some(vec[..])
result = Some(vec[..])
case 4.
v1 = None
v2 = None
result = None
Is there a generalized way to implement this?

You can just use a match statement representing your cases:
let result = match (v1, v2) {
(res#Some(_), None) => res,
(None, res#Some(_)) => res,
(Some(r1), Some(r2)) => Some(r1.into_iter().chain(r2).collect()),
_ => None
};
Playground

You can take advantage of the fact that Options can be converted to Iterators and use Iterator::reduce:
v1.into_iter()
.chain(v2.into_iter())
.reduce(|mut v1, mut v2| {
v1.append(&mut v2);
v1
})
Chaining the two Option iterators will give us an iterator that yields either 0 (if both v1 and v2 were None), 1 (if either v1 or v2 was None), or 2 (if both v1 and v2 were not None) vectors. Iterator::reduce will only "reduce" the iterator with the closure if there are 2 or more vectors in the iterator and otherwise will return the only vector, if any, in the iterator.
Rust Playground

Related

Z3py: Add value to computed result and make another check

I want to solve the following example with Z3:
input = 0
if input < 5:
var v1 = 5
input += v1
input *= v1
if input > 5:
return True
else:
return False
How do I turn this logic into Z3? This is what I have so far.
input = Int("input")
v1 = Int("v1")
solver = Solver()
solver.add(v1 == 5)
solver.add(input < 5)
solver.check()
model = solver.model()
for d in model.decls():
# prints:
# "input = 4"
# "v1 = 5"
print ("%s = %s" % (d.name(), model[d]))
How do I add 5 to input and multiple input with 5 that I can later check if it's greater than 5?
The standard technique for modeling such imperative programs is to convert it to SSA (static single assignment) form, essentially by duplicating each assigned variable at each position. For details, see: https://en.wikipedia.org/wiki/Static_single_assignment_form
Based on this idea, I'd model your program as follows:
from z3 import *
v1 = Int('v1')
input0, input1, input2 = Ints('input0 input1 input2')
solver = Solver()
solver.add(input0 == 0)
solver.add(Implies(input0 < 5, v1 == 5))
solver.add(input1 == If(input0 < 5, input0 + v1, input0))
solver.add(input2 == If(input0 < 5, input1 * v1, input1))
result = Bool('result')
solver.add(result == (input2 > 5))
print(solver.check())
m = solver.model()
print ("input = %s" % m[input2])
print ("v1 = %s" % m[v1])
print ("result = %s" % m[result])
When run, this prints:
sat
input = 25
v1 = 5
result = True
which shows the final values of the variables involved and the returned value.

z3py: restricting solution to a set of values

I am new to Z3-solver python. I am trying to define a list and confine all my outputs to that list for a simple operation like xor.
My code:
b=Solver()
ls=[1,2,3,4,5] #my list
s1=BitVec('s1',32)
s2=BitVec('s2',32)
x=b.check(s1^s2==1, s1 in ls, s2 in ls) #s1 and s2 belongs to the list, however, this is not the correct way
if x==sat: print(b.model().eval)
The check function doesn't work like that.
Can anyone please help me in figuring how to do this in a different way?
Ans: s1=2,s2=3; since 2xor3 = 1 and s2,s3 belongs to ls=[1,2,3,4,5]
The easiest way to do this would be to define a function that checks if a given argument is in a list provided. Something like:
from z3 import *
def oneOf(x, lst):
return Or([x == i for i in lst])
s1 = BitVec('s1', 32)
s2 = BitVec('s2', 32)
s = Solver()
ls = [1, 2, 3, 4, 5]
s.add(oneOf(s1, ls))
s.add(oneOf(s2, ls))
s.add(s1 ^ s2 == 1)
print (s.check())
print (s.model())
When I run this, I get:
sat
[s2 = 2, s1 = 3]
which I believe is what you're after.

Is there a way to return a pair of integers using the let construct in standard ML?

I am trying to return a pair of sums using the let construct in sml. Every way I have tried will only return one value. I have tried creating a list by using cons (::) and then returning the list, but that gives an error as well.
val t = [(3,4), (4,5), (5,6)];
fun sumPairs(nil) = 0
| sumPairs((x,y)::zs) =
let
val sumFirst = x + sumPairs(zs)
val sumSecond = y + sumPairs(zs)
in
(sumFirst, sumSecond) <how would I return this as a tuple or list?>
end;
sumPairs(t);
The problem is not with (sumFirst, sumSecond) or with let specifically, but with the rest of your code.
The base case and the recursions say that sumPairs produces an int, not a pair of ints.
Because of this, there is a conflict when you try produce a pair.
Your base case should be (0,0), not 0, since it must be a pair.
You also need to deconstruct the result from the recursion since that produces a pair, not an integer.
Like this
fun sumPairs nil = (0, 0)
| sumPairs ((x,y)::zs) =
let
val (sumFirst, sumSecond) = sumPairs zs
in
(x + sumFirst, y + sumSecond)
end;

R-style logical vector operation in Nim

does anyone know if Nim has a function like 'ifelse' in R that allows to apply conditional calculations on vectors, equivalent to:
a<-c(1,2,3,4)
b<-c(7,2,7,4)
c<-ifelse(a==b,a*b,a+b)
using a loop and 'if, else' statement would be too slow for large vectors.
Ok so. In Nim a Tuple uses the same idea as a vector in R: structural typing. Hopefully I'm on track here. Nim has the ability to do stuff during compile time as opposed to runtime, so the functions that are built in for Tuples, like == have a loop in their source code, but in actuality the loop is unraveling at compile time, and the fields are being referenced directly at runtime. So for speed, Tuple == Tuple will be as fast as it could possibly be, regardless of the number of fields in the Tuple. This can be verified via the source code.
I am certain you can do exactly what you are asking after verifying that this little function I wrote works since * wasn't built in for Tuples:
let
v1 = (1,2,3,4)
v2 = (7,2,7,4)
proc `*`[T:tuple](x, y: T): T =
for a,b in fields(x, result):
b = a
for a,b in fields(y, result):
b = b * a
echo $(v1 * v2) #prints (Field0: 7, Field1: 4, Field2: 21, Field3: 16)
We could write the same function for addition:
let
v1 = (1,2,3,4)
v2 = (7,2,7,4)
proc `+`[T:tuple](x, y: T): T =
for a,b in fields(x, result):
b = a
for a,b in fields(y, result):
b = b + a
echo $(v1 + v2)
Here's a full example which is a combination of the forum convo and the functions above:
proc `+`[T:tuple](x, y: T): T =
for a,b in fields(x, result):
b = a
for a,b in fields(y, result):
b = b + a
proc `*`[T:tuple](x, y: T): T =
for a,b in fields(x, result):
b = a
for a,b in fields(y, result):
b = b * a
let
a = (1,2,3,4)
b = (7,2,7,4)
c = if v1 == v2: v1 * v2 else: v1 + v2
Hope this helps!

How to make LPeg.match return nil

I'm currently getting familiar with the LPeg parser module. For this I want to match a version string (e.g. 11.4) against a list.
Such a list is a string with a tight syntax that can also contain ranges. Here is an EBNF-like, but in any case quite simple grammar (I write it down because LPeg code below can be a bit difficult to read):
S = R, { ',', R }
R = N, [ '-', N ]
N = digit+, [ '.', digit+ ]
An example string would be 1-9,10.1-11,12. Here is my enormous code:
local L = require "lpeg"
local LV, LP, LC, LR, floor = L.V, L.P, L.C, L.R, math.floor
local version = "7.25"
local function check(a, op, b)
if op and a+0 <= version and version <= b+0 then
return a..op..b -- range
elseif not op and floor(version) == floor(a+0) then
return a -- single item
end
end
local grammar = LP({ "S",
S = LV"R" * (LP"," * LV"R")^0,
R = LV"V" * (LC(LP"-") * LV"V")^-1 / check,
V = LC(LV"D" * (LP"." * LV"D")^-1),
D = (LR("09")^1),
})
function checkversion(str)
return grammar:match(str)
end
So you would call it like checkversion("1-7,8.1,8.3,9") and if the current version is not matched by the list you should get nil.
Now, the trouble is, if all calls to check return nothing (meaning, if the versions do not match), grammar:match(...) will actually have no captures and so return the current position of the string. But this is exactly what I do not want, I want checkversion to return nil or false if there is no match and something that evaluates to true otherwise, actually just like string:match would do.
If I on the other hand return false or nil from check in case of a non-match, I end up with return values from match like nil, "1", nil, nil which is basically impossible to handle.
Any ideas?
I think you can or + it with a constant capture of nil:
grammar = grammar + lpeg.Cc(nil)
This is the pattern I eventually used:
nil_capturing_pattern * lpeg.Cc(nil)
I incorporated it into the grammar in the S rule (Note that this also includes changed grammar to "correctly" determine version order, since in version numbering "4.7" < "4.11" is true, but not in calculus)
local Minor_mag = log10(Minor);
local function check(a, am, op, b, bm)
if op then
local mag = floor(max(log10(am), log10(bm), Minor_mag, 1))+1;
local a, b, v = a*10^mag+am, b*10^mag+bm, Major*10^mag+Minor;
if a <= v and v <= b then
return a..op..b;
end
elseif a == Major and (am == "0" or am == Minor) then
return a.."."..am;
end
end
local R, V, C, Cc = lpeg.R, lpeg.V, lpeg.C, lpeg.Cc
local g = lpeg.P({ "S",
S = V("R") * ("," * V("R"))^0 * Cc(nil),
R = (V("Vm") + V("VM")) * (C("-") * (V("Vm") + V("VM")))^-1 / check,
VM = V("D") * Cc("0"),
Vm = V("D") * "." * V("D"),
D = C(R("09")^1),
});
Multiple returns from match are not impossible to handle, if you catch them in a way that makes handling them easier. I added a function matched that does that, and added the fallback return of false to your check.
do
local L = require "lpeg"
local LV, LP, LC, LR, floor = L.V, L.P, L.C, L.R, math.floor
local version = 6.25
local function check(a, op, b)
if op and a+0 <= version and version <= b+0 then
return a..op..b -- range
elseif not op and floor(version) == floor(a+0) then
return a -- single item
end
return false
end
local grammar = LP({ "S",
S = LV"R" * (LP"," * LV"R")^0,
R = LV"V" * (LC(LP"-") * LV"V")^-1 / check,
V = LC(LV"D" * (LP"." * LV"D")^-1),
D = (LR("09")^1),
})
local function matched(...)
local n = select('#',...)
if n == 0 then return false end
for i=1,n do
if select(i,...) then return true end
end
return false
end
function checkversion(ver,str)
version = ver
return matched(grammar:match(str))
end
end
I enclosed the whole thing in do ... end so that the local version which is used here as an upvalue to check would have constrained scope, and added a parameter to checversion() to make it clearer to run through few test cases. For example:
cases = { 1, 6.25, 7.25, 8, 8.5, 10 }
for _,v in ipairs(cases) do
print(v, checkversion(v, "1-7,8.1,8.3,9"))
end
When run, I get:
C:\Users\Ross\Documents\tmp\SOQuestions>q18793493.lua
1 true
6.25 true
7.25 false
8 true
8.5 true
10 false
C:\Users\Ross\Documents\tmp\SOQuestions>
Note that either nil or false would work equally well in this case. It just feels saner to have collected a list that can be handled as a normal Lua array-like table without concern for the holes.

Resources