How to yield results in table without duplicate result in Cypher? - cypher

Say I have node X that links to node A1, A2, A3 with edge A, node B1, B2 with edge B, and node C1 with edge C. I want to have a query like this:
match (x)-[:A]->(a)
match (x)<-[:B]-(b)
match (x)-[:C]-(c)
where x.name="X"
return a.name,b.name,c.name
And the result is this table:
a.name
b.name
c.name
A1
B1
C1
A2
B2
A3
Not a table of 6 combinations. Is that possible? The Neo4j Cypher Manual of RETURN isn't useful.

I would do this, with the advantage over Nathan's answer that it also yields a result in case some of the edge types are missing, e.g. when there is no B edge.
MATCH (x) WHERE x.name = 'X'
WITH x,
[(x)-[:A]->(a) | a] AS allAs,
[(x)<-[:B]-(b) | b] AS allBs,
[(x)-[:C]-(c) | c] AS allCs
WITH x, allAs, allBs, allCs, apoc.coll.max([size(allAs), size(allBs), size(allCs)]) as maxSize
UNWIND range(0, maxSize -1) as index
RETURN allAs[index].name as A, allBs[index].name as B, allCs[index].name as C

This will return each node matched with a, b, and c in exactly one row of the output.
match (x)-[:A]->(a)
where x.name="X"
WITH x, collect(a) as allAs
match (x)<-[:B]-(b)
WITH x, allAs, collect(b) as allBs
match (x)-[:C]-(c)
WITH x, allAs, allBs, collect(c) as allCs
WITH x, allAs, allBs, allCs, apoc.coll.max([size(allAs), size(allBs), size(allCs)]) as maxSize
UNWIND range(0, maxSize -1) as index
RETURN allAs[index].name as A, allBs[index].name as B, allCs[index].name as C

Related

Inverting a function via CLP(FD) in pure Prolog

Lets take this function:
function gcd(a, b)
while a ≠ b
if a > b
a := a − b
else
b := b − a
return a
How would we code gcd/3 in pure Prolog, so that it can be inverted. The Prolog predicate should for example compute gcd(2,3)=1. But if we would ask what are the a, b such that gcd(a,b)=1, we would also get by the same Prolog predicate:
/* one while iteration */
2, 1
1, 2
/* two while iterations */
3, 1
2, 3
3, 2
1, 3
/* Etc... */
Prolog seems to be especially suited since it can enumerate solutions.
I first tried to literally translate the GCD function
into a Prolog code. The first clause is for when a ≠ b is false,
which means we can terminate the function. Otherwise we
recurse into the two cases:
euclid(A,A,A).
euclid(A,B,R) :- A #< B, C #= B-A, euclid(A,C,R).
euclid(A,B,R) :- A #> B, C #= A-B, euclid(C,B,R).
We can test, seems to work fine, except it has choice points.
But the choice points are kind of the price we have to pay for
using CLP(FD) and programming pure Prolog without cut:
?- euclid(17,13,X).
X = 1 ;
No
But using euclid/3 for enumeration isn't very satisfactory,
the result is only one execution branch of the GCD function:
?- euclid(A,B,1).
A = 1,
B = 1 ;
A = 1,
B = 2 ;
A = 1,
B = 3 ;
A = 1,
B = 4 ;
Now we can do the following and encode a path P through the GCD
function by a binary number. When we terminate the path will be P=1.
Otherwise we use the lower bit of P to encode which of the two remaining
clauses of the GCD were chosen:
euclid(A,A,1,A).
euclid(A,B,P,R) :- A #< B, C #= B-A, P #= 2*Q, Q #> 0, euclid(A,C,Q,R).
euclid(A,B,P,R) :- A #> B, C #= A-B, P #= 2*Q+1, Q #> 0, euclid(C,B,Q,R).
The resulting Prolog predicate is indeed bidirectional:
?- euclid(17,13,P,X).
P = 241,
X = 1 ;
No
?- euclid(A,B,241,1).
A = 17,
B = 13 ;
No
We can also use it to arbitrarily enumerate, although only with
the help of between/3 and maybe not the most efficient, but it wurks:
?- between(1,7,P), euclid(A,B,P,1), write(B/A), nl, fail; true.
1/1
2/1
1/2
3/1
2/3
3/2
1/3
Yes
Edit 04.02.2021:
Oh, interesting, this works also. But the result is differently ordered:
?- P #< 8, euclid(A,B,P,1), write(B/A), nl, fail; true.
1/1
2/1
3/1
3/2
1/2
2/3
1/3
true.
This solution uses an argument to keep track of the current tier of the loop:
gcd(A, B, G):-
gcd(_, A, B, G).
gcd(Tier, A, B, G):-
Tier1 #= Tier - 1,
Tier1 #>= 0,
zcompare(Order, A, B),
gcd(Order, Tier1, A, B, G).
gcd(=, 0, G, G, G).
gcd(>, Tier, A, B, G):-
A1 #= A - B,
gcd(Tier, A1, B, G).
gcd(<, Tier, A, B, G):-
B1 #= B - A,
gcd(Tier, A, B1, G).
So when you want to get a tiered enumeration you my write:
?- between(1,3,Tier), gcd(Tier, A,B,1), write(B/A), nl, fail; true.
1/1
1/2
2/1
1/3
2/3
3/2
3/1
true.

Name the output of an expression in Tensorflow

I wonder whether it's possible to give a name to the output of a certain expression to retrieve it from the graph at another part of the code.
For example
def A(a, b):
c = a + b
d = d * a
return d
For debug purposes it would be nice if I could pull out c at another position without returning it through the entire function hierarchy.
Any ideas?
Thanks in advance!
I'm assuming a and b are tensors.
Either you give a name to c using tf.identity
def A(a, b):
c = a + b
c = tf.identity(c, name = "c")
d = d * a
return d
Either you use the tf.add operation instead of +:
def A(a, b):
tf.add(a, b, name = "c")
d = d * a
return d
Either way, you get retrieve c with tf.get_variable('c:0') (You might need to precise the scope if any.)

xlrd dynamic variables python

I can make it work like this:
book = xlrd.open_workbook(Path+'infile')
sheet = book.sheet_by_index(0)
A, B, C, D = ([] for i in range (4))
A = sheet.col_values(0)
B = sheet.col_values(1)
C = sheet.col_values(2)
D = sheet.col_values(3)
but what I want is to make it work like this:
dyn_var_list = [A, B, C, D]
assert(len(sheet.row_values(0))==len(dyn_var_list))
for index, col in enumerate(sheet.row_values(0)):
dyn_var_list[index].append(col)
however, so far I can only get one value in my lists, using the code above, which is due to the usage of "(0)" after the row_values I guess, but I don't know how to resolve this as of yet.
Try
for c in range(sheet.ncols):
for r in range(sheet.nrows):
dyn_var_list[c].append(sheet.cell(r,c).value)
Here sheet.nrows gives you the number of rows in the sheet.

Oracle Spatial: how to query all polygons what are connected (recursivelly)?

Let's say we have 6 polygons ( A,B,C,D,E, F)in Spatial database.
A touches B,
B touches C and D,
E and F are not connected to other polygons.
A - B
/ \
C D E F
Having Polygon A, I need to query all polygons connected to it , and do it "recursivelly" Cannot describe it better. So the query by A should return A, B, C, D.
Of course, it is possible to do programmatically, first using SDO_RELATE query B by A, and then query C and D by B. But is it possible to do the task with a single query?

Approaches to converting a table of possibilities into logical statements

I'm not sure how to express this problem, so my apologies if it's already been addressed.
I have business rules summarized as a table of outputs given two inputs. For each of five possible value on one axis, and each of five values on another axis, there is a single output. There are ten distinct possibilities in these 25 cells, so it's not the case that each input pair has a unique output.
I have encoded these rules in TSQL with nested CASE statements, but it's hard to debug and modify. In C# I might use an array literal. I'm wondering if there's an academic topic which relates to converting logical rules to matrices and vice versa.
As an example, one could translate this trivial matrix:
A B C
-- -- -- --
X 1 1 0
Y 0 1 0
...into rules like so:
if B OR (A and X) then 1 else 0
...or, in verbose SQL:
CASE WHEN FieldABC = 'B' THEN 1
WHEN FieldABX = 'A' AND FieldXY = 'X' THEN 1
ELSE 0
I'm looking for a good approach for larger matrices, especially one I can use in SQL (MS SQL 2K8, if it matters). Any suggestions? Is there a term for this type of translation, with which I should search?
Sounds like a lookup into a 5x5 grid of data. The inputs on axis and the output in each cell:
Y=1 Y=2 Y=3 Y=4 Y=5
x=1 A A D B A
x=2 B A A B B
x=3 C B B B B
x=4 C C C D D
x=5 C C C C C
You can store this in a table of x,y,outvalue triplets and then just do a look up on that table.
SELECT OUTVALUE FROM BUSINESS_RULES WHERE X = #X and Y = #Y;