Consider the following code:
select (some columns)
from efdan_setup a,crit_efdan_val b,efdan c
where a.dan *= c.code
and b.codef *= c.codef
and b.mhnmis *= c.mhnmis
and b.etmis *= c.etmis
and b.ebdmis *= c.ebdmis
and b.mhnet *= c.mhnet
and b.mhnet_plir *= c.mhnet_plir
I am not very familiar with old-style joins, and I've read enough to understand I should probably change this. I wonder which is the new style equivelant. My guess:
from
crit_efdan_val b
left join efdan c on
b.codef = c.codef
and b.mhnmis = c.mhnmis
and b.etmis = c.etmis
and b.ebdmis = c.ebdmis
and b.mhnet = c.mhnet
and b.mhnet_plir = c.mhnet_plir
right join fdan_setup a on a.dan = c.code
You are almost there - but mixing left joins and right joins is almost as bad as mixing matter and anti-matter.
In fact, some people (including myself) would rather avoid right joins altogether and stick with left joins only.
Here's how I would write this:
from efdan_setup a
left join efdan c
on a.dan = c.code
left crit_efdan_val b
on b.codef = c.codef
and b.mhnmis = c.mhnmis
and b.etmis = c.etmis
and b.ebdmis = c.ebdmis
and b.mhnet = c.mhnet
and b.mhnet_plir = c.mhnet_plir
Related
I'm experimenting a bit with boolector so I'm trying to create model for simple code. Suppose that I have the following pseudo code:
int a = 5;
int b = 4;
int c = 3;
For this simple set of instructions I can create the model and all works fine. The problem is when I have other instructions after that like
b = 10;
c = 20;
Obviously it fails to generate the model because b cannot be equal to 4 and 10 within the same module. One of the maintainer suggested me to use boolector_push and boolector_pop in order to create new Contexts when needed.
The code for boolector_push is :
void
boolector_push (Btor *btor, uint32_t level)
{
BTOR_ABORT_ARG_NULL (btor);
BTOR_TRAPI ("%u", level);
BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
"incremental usage has not been enabled");
if (level == 0) return;
uint32_t i;
for (i = 0; i < level; i++)
{
BTOR_PUSH_STACK (btor->assertions_trail,
BTOR_COUNT_STACK (btor->assertions));
}
btor->num_push_pop++;
}
Instead for boolector_pop is
void
boolector_pop (Btor *btor, uint32_t level)
{
BTOR_ABORT_ARG_NULL (btor);
BTOR_TRAPI ("%u", level);
BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
"incremental usage has not been enabled");
BTOR_ABORT (level > BTOR_COUNT_STACK (btor->assertions_trail),
"can not pop more levels (%u) than created via push (%u).",
level,
BTOR_COUNT_STACK (btor->assertions_trail));
if (level == 0) return;
uint32_t i, pos;
BtorNode *cur;
for (i = 0, pos = 0; i < level; i++)
pos = BTOR_POP_STACK (btor->assertions_trail);
while (BTOR_COUNT_STACK (btor->assertions) > pos)
{
cur = BTOR_POP_STACK (btor->assertions);
btor_hashint_table_remove (btor->assertions_cache, btor_node_get_id (cur));
btor_node_release (btor, cur);
}
btor->num_push_pop++;
}
In my opinion, those 2 functions maintains track of the assertions generated using boolector_assert so how is it possible to obtain the final and correct model using boolector_push and boolector_pop considering that the constraints are going to be the same?
What am I missing?
Thanks
As you suspected, solver's push and pop methods aren't what you're looking for here. Instead, you have to turn the program you are modeling into what's known as SSA (Static Single Assignment) form. Here's the wikipedia article on it, which is quite informative: https://en.wikipedia.org/wiki/Static_single_assignment_form
The basic idea is that you "treat" your mutable variables as time-varying values, and give them unique names as you make multiple assignments to them. So, the following:
a = 5
b = a + 2
c = b + 3
c = c + 1
b = c + 6
becomes:
a0 = 5
b0 = a0 + 2
c0 = b0 + 3
c1 = c0 + 1
b1 = c1 + 6
etc. Note that conditionals are tricky to deal with, and generally require what's known as phi-nodes. (i.e., merging the values of branches.) Most compilers do this sort of conversion automatically for you, as it enables many optimizations down the road. You can either do it by hand, or use an algorithm to do it for you, depending on your particular problem.
Here's another question on stack-overflow, that's essentially asking for something similar: Z3 Conditional Statement
Hope this helps!
I'm trying to use class behavior in lua where there is a ship that has two other classes pos and vector
But I cannot get it working like I assumed I would be able to
Point = {x=0, y=0}
function Point:new(p)
p = p or {}
return p
end
Ship =
{
pos = {Point:new{x=0,y=0}},
vector = {Point:new{x=0,y=0}} -- I thought this would be sufficient for access being available for vector
}
-- create new ship class
function Ship:new(pos)
p = p or {}
p.pos = pos
p.vector = Point:new{x=0,y=0} -- I need to do this or accessing vector will crash (The problem)
return p
end
-- Create new ship...
plrShip = Ship:new{}
plrShip.pos.x = 300
plrShip.pos.y = 300
If anyone knows how to make the above code cleaner/better I would be thankful
You can use metatables to set default fields. (I've made some assumptions about what you're trying to do. If this doesn't work for you, please add some clarification to your question.)
local Point = {x=0, y=0}
Point.__index = Point
function Point:new(p)
p = p or {}
setmetatable(p, self)
return p
end
-- create new ship class
local Ship = {}
Ship.__index = Ship
function Ship:new(pos)
setmetatable(pos, Point)
local p = {pos = pos, vector = Point:new()}
setmetatable(p, self)
return p
end
-- Create new ship...
local plrShip = Ship:new{}
plrShip.pos.x = 300
plrShip.pos.y = 300
I found solution to do this, it still not perfect but only I got working was this modified code:
Ship =
{
pos = Point:new{x=0,y=0},
vector = Point:new{x=0,y=0}
}
function Ship:new()
p = p or {}
p.pos = self.pos
p.vector = self.vector
return p
end
plrShip = Ship:new()
plrShip.pos.x = 300
plrShip.pos.y = 300
I need to traverse all vertices that are connected by edges where the property 'dependence' is 'true'
This is what I have so far:
SELECT
FROM (TRAVERSE *
FROM (SELECT outE() FROM 9:5)
WHILE (#class = 'E' AND dependence = 'yes') OR #class = 'V')
WHERE #class = 'V'
Although im not sure if is the best way to do it, this seems to work fine following only the paths where edges have 'dependence' = 'yes'.
Now, There could be more than one path generated, and I need to get the last vertex from each path/branch.
traverserdVertex(-1) should return the last one, but im guessing that is from the whole traversal so is no good. (and it looks like there's a bug because it retrieves more than one)
The outer SELECT returns the whole bag of vertices so I'm thinking that maybe finding the ones that doesn't have an outgoing edge with dependence='yes' might solve it, although I'm not sure how to do it nicely.
SOLUTION:
SELECT
FROM (TRAVERSE *
FROM (SELECT outE() FROM 9:5)
WHILE (#class = 'E' AND dependence = 'yes') OR #class = 'V')
WHERE #class = 'V' AND NOT (outE() contains (dependence='yes'))
This effectively returns the last vertex from each branch. I'm open to any other option, I'm wondering if it could be improved.
I tried with an example by building the following graph
The javascript function "myFunction" has three parameters which are ridVertex, property and value
var g=orient.getGraph();
var previous=[];
var currently=[];
var node=[];
var b=g.command("sql","select from v where #rid =" + ridVertex);
if(b.length>0){
previous.push(b[0]);
node.push(b[0]);
do{
for(i=0;i<previous.length;i++){
var edges=g.command("sql","select expand(outE()) from V where #rid = "+ previous[i].getId());
var myVertex=[];
for(j=0;j<edges.length;j++){
var edge=edges[j];
var dependence=edge.getProperty(property);
if(dependence==value){
var vIn=edge.getProperty("in");
myVertex.push(vIn);
}
}
if(myVertex.length>0){
setPaths();
}
}
change();
}while(previous.length>0);
}
return node;
function setPaths(){
for (m = 0; m < node.length; m++) {
var lastId=node[m].getId().toString();
var idOut=previous[i].getId().toString();
if (lastId==idOut) {
for(r=0;r<myVertex.length;r++){
var vertex=myVertex[r];
node.push(vertex);
currently.push(vertex);
}
node.splice(m,1);
break;
}
}
}
function change(){
previous=[];
for (indice=0;indice<currently.length;indice++)
previous.push(currently[indice]);
currently=[];
}
Using the following command
select expand(result) from (select myFunction("#9:0","dependence","yes") as result)
the paths are A -> D and A -> B -> C -> G and then will be returned the verteces D and G
The following is a slight simplification of #sebastian's solution, using Allesandro's graph (with dependentOn.value being 0 or 1):
select from
(TRAVERSE * FROM (select from Circle where name="A")
while (#CLASS="dependentOn" and value=1) OR #CLASS="Circle")
where #CLASS='Circle' AND NOT (outE().value contains 1)
----+-----+------+----+--------------
# |#RID |#CLASS|name|in_dependentOn
----+-----+------+----+--------------
0 |#11:6|Circle|G |[#12:4]
1 |#11:3|Circle|D |[#12:1]
I'm trying to write a Custom KlocWork checker for c++ however im stuck with an issue:
When we have an expression like this one:
x = y + z;
I want to access the left node which is the variable 'x' but also both variables from the Right node(Left and Right from the RIGHT NODE) i don't know how to access every variable, so far i have this in my checker:
// BinaryExpr [ getOperationCode() = KTC_OPCODE_ASSIGN]
[$exprL:= Left]
[$size1:= $exprL.getTypeSize()]
[$exprR:= Right]
[$exprR.getOperationCode() = KTC_OPCODE_ADD]
Which detects every BinaryExpression with another expression on the Left Node(store in $exprR) but after that i don't know how to access Left and Right childs of $exprR.
Thanks in advance for any help!
There are two nested expressions here, and you want to store the Left node of the assignment and then continue to traverse the AST further using the full pattern to the second binary expression node to get the left and right nodes of the add. For example:
// BinaryExpr [getOperationCode() = KTC_OPCODE_ASSIGN] [$exprOL:= Left]
Here we find and store the left node of the assignment expression.
// BinaryExpr [getOperationCode() = KTC_OPCODE_ASSIGN] [$exprOL:= Left] / Right::BinaryExpr [getOperationCode() = KTC_OPCODE_ADD]
And then we continue on to get the addition expression. Finally, we can grab Left and Right of this expression:
// BinaryExpr [getOperationCode() = KTC_OPCODE_ASSIGN] [$exprOL:= Left] / Right::BinaryExpr [getOperationCode() = KTC_OPCODE_ADD]
[$exprL:= Left]
[$exprR:= Right]
You can use the println() function to test this. So the complete expression
// BinaryExpr [getOperationCode() = KTC_OPCODE_ASSIGN] [$exprOL:= Left] / Right::BinaryExpr [getOperationCode() = KTC_OPCODE_ADD]
[$exprL:= Left]
[$exprR:= Right]
[$exprOL.getName().println()]
[$exprL.getName().println()]
[$exprR.getName().println()]
for the following code:
int func (int x, int y)
{
int local;
local = x;
local = x + y;
local = y - x;
return local;
}
Would print out:
local
x
y
I need to merge two tables, with the contents of the second overwriting contents in the first if a given item is in both. I looked but the standard libraries don't seem to offer this. Where can I get such a function?
for k,v in pairs(second_table) do first_table[k] = v end
Here's what i came up with based on Doug Currie's answer:
function tableMerge(t1, t2)
for k,v in pairs(t2) do
if type(v) == "table" then
if type(t1[k] or false) == "table" then
tableMerge(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
t1[k] = v
end
end
return t1
end
Wouldn't this work properly?
function merge(t1, t2)
for k, v in pairs(t2) do
if (type(v) == "table") and (type(t1[k] or false) == "table") then
merge(t1[k], t2[k])
else
t1[k] = v
end
end
return t1
end
For numeric-index table merging:
for k,v in pairs(secondTable) do table.insert(firstTable, v) end
Doug Currie's answer is the simplest for most cases. If you need more robust merging of tables, consider using the merge() method from the Penlight library.
require 'pl'
pretty.dump(tablex.merge({a=1,b=2}, {c=3,d=4}, true))
-- {
-- a = 1,
-- d = 4,
-- c = 3,
-- b = 2
-- }
Here's iterative version for deep merge because I don't like potential stack overflows of recursive.
local merge_task = {}
function merge_to_left_o(orig, new)
merge_task[orig] = new
local left = orig
while left ~= nil do
local right = merge_task[left]
for new_key, new_val in pairs(right) do
local old_val = left[new_key]
if old_val == nil then
left[new_key] = new_val
else
local old_type = type(old_val)
local new_type = type(new_val)
if (old_type == "table" and new_type == "table") then
merge_task[old_val] = new_val
else
left[new_key] = new_val
end
end
end
merge_task[left] = nil
left = next(merge_task)
end
end
I preferred James version for its simplicity and use it in my utils.lua - i did add a check for table type for error handling.
function merge(a, b)
if type(a) == 'table' and type(b) == 'table' then
for k,v in pairs(b) do if type(v)=='table' and type(a[k] or false)=='table' then merge(a[k],v) else a[k]=v end end
end
return a
end
Thanks for this nice function which should be part of the table class so you could call a:merge(b) but doing table.merge = function(a, b) ... did not work for me. Could even be compressed to a one liner for the real nerds :)
Like Doug Currie said, you can use his function, but there is a problem with his method. If first_table has things in it's k index, the function will over write it.
I'm assuming you're trying to merge these tables, not overwrite index's and value's. So this would be my method, it's very similar but is used for merging tables.
for _, v in pairs(second_table) do table.insert(first_table, v) end
The only problem with this solution is that the index is set as numbers, not as strings. This will work with tables with numbers as the index, and for tables with strings as their index, use Doug Currie's method.
Doug Currie's method:
for k,v in pairs(second_table) do first_table[k] = v end
Extending this great answer, https://stackoverflow.com/a/1283399/1570165, I would like to go with a (pure) functional approach like this one below:
-- example values
local t1 = { a = 0, b = 2 }
local t2 = { a = 1, c = 3 }
-- merge function that takes functional approach
local merge = function(a, b)
local c = {}
for k,v in pairs(a) do c[k] = v end
for k,v in pairs(b) do c[k] = v end
return c
end
-- t1 and t2 value still same after merge
print(merge(t1, t2)) -- { a = 1, b = 2, c = 3 }
print(t2) -- { a = 1, c = 3 }
print(t1) -- { a = 0, b = 2 }
for k,v in pairs(t2) do t1[k] = v end
key for string solution