Find the shortest path in DLV - path

I am trying to find all the paths in a graph with minimum distance using DLV. Say I have the following graph:
I am expecting to obtain the predicates (I hope I don't skip any):
path(a, b, 1), path(a, d, 1), path(a, e, 1), path(a, c, 2)
path(b, a, 1), path(b, c, 1), path(d, d, 2), path(b, e, 2)
path(c, b, 1), path(c, e, 1), path(c, a, 2), path(c, d, 3)
path(d, a, 1), path(d, b, 2), path(d, e, 2), path(d, c, 3)
path(e, a, 1), path(e, c, 1), path(e, d, 2), path(e, b, 2)
I assume that you can travel an arch both left or right. So, I tried the following:
path(X, Y, 1) :- arc(X, Y).
path(Y, X, 1) :- arc(X, Y).
path(X, Z, L) :- path(X, Y, M), path(Y, Z, N),
X!=Z,
L = M + N,
not path(X, Z, V), V < L, #int(V)
The idea of the third rule was to add 2 existing paths if they are not going back (X!=Z) and there is not already a path connecting the same edges with a shorter distance (not path(X, Z, V), V < L, #int(V)). I had to add #int(V) because otherwise the rule was not safe. I don't know if there is a better way of resolving this safety issue with an integer value.
When I run this code (with the flag -N=5 to set #maxint=5) I get paths that should not be there, for example, path(d,a,5). I don't know if the problem is with the #int(V) or something else but I wouldn't expect these paths to appear since I already have a path(d,a,1). Probably it is because of #int(V) but I can't figure out how to do this right.
Can anyone help me solve this? Thanks in advance.

Solution to the problem using lists to keep track of the path:
path(X, Y, [X, Y], 1) :- arc(X, Y).
path(Y, X, [Y, X], 1) :- arc(X, Y).
path(X, Z, P, D) :- path(X, Y, P1, D1),
path(Y, Z, P2, 1),
#insLast(P1, Z, P),
D = D1 + 1,
not #member(Z, P1).
shortest_path(X, Y, D) :- node(X), node(Y),
#min{L: path(X, Y, P, L)} = D.
Solution without the need of lists (with the help of CapelliC)
path(X, Y, 1) :- arc(X,Y).
path(Y, X, 1) :- arc(X,Y).
path(X, Y, D) :- path(X,Z,D0), arc(Z,Y),
#count{A: node(A)} = Max,
D0<Max, X != Y,
D = D0+1.
shorter_paths(X, Y, D) :- node(X), node(Y),
#min{L: path(X, Y, L)} = D.
Note that we need to define all nodes with a predicate node() and that the predicate arc() assumes that the edge of the graph is bidirectional.

examples/spaths.dl from DES distribution. See the commented code below... -
%
% Shortest Paths in a Graph
%
% Datalog Formulation
%
% Program: Shortest paths in a graph
% Author : Fernando Sáenz-Pérez
% Date : September, 2009
edge(a,b).
edge(a,c).
edge(b,a).
edge(b,d).
path(X,Y,1) :-
edge(X,Y).
path(X,Y,L) :-
path(X,Z,L0),
edge(Z,Y),
count(edge(A,B),Max),
L0<Max,
L is L0+1.
spaths(X,Y,L) :-
min(path(X,Y,Z),Z,L).
% Note that the following is not stratifiable in DES
%sp(X,Y,1) :-
% edge(X,Y).
%sp(X,Y,L) :-
% sp(X,Z,L0),
% not(shorter(X,Z,L0)),
% edge(Z,Y),
% L is L0+1.
%shorter(X,Y,L) :-
% sp(X,Y,L0),
% L0<L.

Related

add iteratively in z3

I want to check the value of a, b, c, and if value 'a' equals to 1, 'x' is added one. We continue the process for values 'b' and 'c'.
So if a=1, b=1, c=1, the result of x should be 3.
if a=1, b=1, c=0, so the result of x should be 2.
Any methods to be implemented in z3?
The source code looks like this:
from z3 import *
a, b, c = Ints('a b c')
x, y = Ints('x y')
s = Solver()
s.add(If(a==1, x=x + 1, y = y-1))
s.add(If(b==1, x=x + 1, y = y-1))
s.add(If(c==1, x=x + 1, y = y-1))
s.check()
print s.model()
Any suggestions about what I can do?
This sort of "iterative" processing is usually modeled by unrolling the assignments and creating what's known as SSA form. (Static single assignment.) In this format, every variable is assigned precisely once, but can be used many times. This is usually done by some underlying tool as it is rather tedious, but you can do it by hand as well. Applied to your problem, it'd look something like:
from z3 import *
s = Solver()
a, b, c = Ints('a b c')
x0, x1, x2, x3 = Ints('x0 x1 x2 x3')
s.add(x0 == 0)
s.add(x1 == If(a == 1, x0+1, x0))
s.add(x2 == If(b == 1, x1+1, x1))
s.add(x3 == If(c == 1, x2+1, x2))
# Following asserts are not part of your problem, but
# they make the output interesting
s.add(b == 1)
s.add(c == 0)
# Find the model
if s.check() == sat:
m = s.model()
print("a=%d, b=%d, c=%d, x=%d" % (m[a].as_long(), m[b].as_long(), m[c].as_long(), m[x3].as_long()))
else:
print "no solution"
SSA transformation is applied to the variable x, creating as many instances as necessary to model the assignments. When run, this program produces:
a=0, b=1, c=0, x=1
Hope that helps!
Note that z3 has many functions. One you could use here is Sum() for the sum of a list. Inside the list you can put simple variables, but also expression. Here an example for both a simple and a more complex sum:
from z3 import *
a, b, c = Ints('a b c')
x, y = Ints('x y')
s = Solver()
s.add(a==1, b==0, c==1)
s.add(x==Sum([a,b,c]))
s.add(y==Sum([If(a==1,-1,0),If(b==1,-1,0),If(c==1,-1,0)]))
if s.check() == sat:
print ("solution:", s.model())
else:
print ("no solution possible")
Result:
solution: [y = 2, x = 2, c = 1, b = 0, a = 1]
If your problem is more complex, using BitVecs instead of Ints can make it run a little faster.
edit: Instead of Sum() you could also simply use addition as in
s.add(x==a+b+c)
s.add(y==If(a==1,-1,0)+If(b==1,-1,0)+If(c==1,-1,0))
Sum() makes sense towards readability when you have a longer list of variables, or when the variables already are in a list.

Functional increment

I am working on a simple function that should, given x, return a tuple (y, z) such that y <= abs(5) + z * 10 = x, where z the smallest possible value.
In C, I would loop over z++ and y++, until their sum matches x.
Currently, I am trying to solve this problem functionally. Please consider the following example:
let foo x =
let rec aux (y, z, q) =
match (y + z * 10) with
q -> (y, z)
|_ -> aux(y + 1, z + 1, q) //How to correctly set the increments?
aux(0, 0, x)
This approach always returns (0, 0), no matter what. I referred to this question, while thinking a solution. I am aware that mutable variables should be avoided, and that is what I do. Unfortunately, I am afraid I missed the point, somewhere, thus I am approaching the problem from the wrong side.
You're introducing a new q binding for the result of the expression evaluated in your first case match rather than comparing against it. What you want is something like this:
match (y + z * 10) with
| r when r = q -> (y, z)
| _ -> aux(y + 1, z + 1, q)
In F# you are generally either within a value expression or a pattern matching expression. When you do this:
match (y + z * 10) with
q -> (y, z)
You're effectively saying: "Calculate y + z * 10 and then always assign the result to a new variable q, ignore this new variable and return (y, z)". This is because q is written in a pattern matching expression as it's just after with.
This is also why you're getting a warning on the next line saying "This rule will never by matched". This is a very common misunderstanding when people are learning F#.
You're not really making use of pattern matching at all when you do this. So I would recommend using an if expression instead:
if y + z * 10 = q
then (y, z)
else aux (y + 1, z + 1, q)
This is actually equivalent to using the ternary operators ? and : in C because it's an expression, not a statement, but it reads more clearly.

semantic web rule use "all"

Assume that I have the following statements:
A p B, A p C, B p C ( p is a symmetric property, i.e. B p A, C p A and C p B)
A v 2, B v 1, C v 1,
I want to use a rule to do something like:
?a p all(?b)
if ?b v 1
than ?a q 'Yes'
that means that you can infer (A q 'Yes'), but B can't since B p A and A v 2(although B p C and C v 1).
[rule: (?a eg:p ?b), (?b eg:v 1) -> (?a eg:q 'Yes')]
I've used the above rule in Jena, but I got A,B,C eg:q 'Yes', which is wrong.
Any help will be greatly appreciated.
Update (originally posted as an answer)
the meaning of (?a p all(?b)) is that I like to get a set which all ?mem in this set fulfill the (?a p ?mem). And all member must fulfill (?mem v 1) to infer (?a q 'Yes').
For example,
A p B and A p C,so I get a set which contains (B, C).since B and C v 1,so A q 'Yes.
B p A and B p C,so I get a set(A, C),but A v 2,so can't infer that B q 'Yes'.
Problem Solved
Thanks to Joshua Taylor.
Firstly, these two rules can't use at the same time.The rule2 should be used after rule1.
And, the rule2 should be [rule2: (?s ?p ?o) noValue(?s, connectedToNonOne) -> (?s q 'Yes')].
but I got A,B,C eg:q 'Yes', which is wrong.
The rule you have actually written in Jena says
For any two individuals X and Y, if (X p Y) and (Y v 1) then (X q 'Yes').
From the rule you've written, this is correct, by:
(A p C), (C v 1) &rightarrow; (A q 'Yes')
(B p C), (C v 1) &rightarrow; (B q 'Yes')
(C p B), (B v 1) &rightarrow; (C q 'Yes')
What you're actually trying to say is:
For any individual X, if for every individual Y, (X p Y) implies (Y v 1), then (X q 'Yes').
In first order logic, your original rule could be written as:
∀ x,y ([p(x,y) &wedge; v(y,1)] &rightarrow; q(x,'yes')
What you're actually trying to capture would be:
∀x[(∀y[p(x,y) &rightarrow; v(y,1)]) &rightarrow; q(x,'yes')]
That's harder to capture in Jena rules, because to check whether (∀y[p(x,y) &rightarrow; v(y,1)]) holds or not, all Jena can do is check whether there are currently any counterexamples. If one were added later, you might have incorrect inferences.
Using the builtins available in the rule reasoner, you could do something with noValue and notEqual along the lines of:
#-- If an individual is disqualified by being
#-- connected to a something that is connected
#-- to something that is not equal to 1, then
#-- add a connectedToNonOne triple.
[rule1:
(?x p ?y), (?y v ?z), notEqual(?z,1)
->
(?x connectedToNonOne true)]
#-- Mark everything that is *not* disqualified
#-- with `q 'Yes'`.
[rule2:
noValue(?x, connectedToNonOne)
->
(?x q 'Yes')

Divide a Point in Elliptic Curve Cryptography

I'm using Elliptic Curve to design a security system. P is a point on elliptic curve. The receiver must obtain P using formula k^-1(kP). The receiver does not know P but knows k. I need to compute k^-1(R) where R=kP. How can I do this using Point Multiplication or Point Addition.
I suggest first learning a bit more about ECC (for example, read some of Paar's book and listen to his course at http://www.crypto-textbook.com/) before tackling something this complex. For this particular question, ask yourself: "What does the inverse of k mean?"
Very interesting question you have! I was happy to implement from scratch Python solution for your task, see code at the bottom of my answer.
Each elliptic curve has an integer order q. If we have any point P on curve then it is well known that q * P = Zero, in other words multiplying any point by order q gives zero-point (infinity point).
Multiplying zero (infinity) point by any number gives zero again, i.e. j * Zero = Zero for any integer j. Adding any point P to zero-point gives P, i.e. Zero + P = P.
In our task we have some k such that R = k * P. We can very easily (very fast) compute Modular Inverse of k modulo order q, using for example Extended Euclidean Algorithm.
Inverse of k modulo q by definition is such that k * k^-1 = 1 (mod q), which by definition of modulus is equal k * k^-1 = j * q + 1 for some integer j.
Then k^-1 * R = k^-1 * k * P = (j * q + 1) * P = j * (q * P) + P = j * Zero + P = Zero + P = P. Thus multiplying R by k^-1 gives P, if k^-1 is inverse of k modulo q.
You can read about point addition and multiplication formulas on this Wiki.
Lets now check our formulas in Python programming language. I decided to implement from scratch simple class ECPoint, which implements all curve operations (addition and multiplication), see code below.
We take any ready-made curve, for example most popular 256-bit curve secp256k1, which is used in Bitcoin. Its parameters can be found here (this doc contains many other popular standard curves), also you can read about this specific curve on Bitcoin Wiki Page.
Following code is fully self-contained Python script, doesn't need any external dependencies and modules. You can run it straight away on any computer. ECPoint class implements all curve arithmetics. Function test() does following operations: we take standard secp256k1 params with some base point G, we compute any random point P = random * G, then we generate random k, compute R = k * P, compute modular inverse k^-1 (mod q) by using function modular_inverse() (which uses extended Euclidean algorithm egcd()), compute found_P = k^-1 * R and check that it is equal to P, i.e. check that k^-1 * R == P, print resulting k^-1 * R. All random values are 256-bit.
Try it online!
def egcd(a, b):
# https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
ro, r, so, s, to, t = a, b, 1, 0, 0, 1
while r != 0:
ro, (q, r) = r, divmod(ro, r)
so, s = s, so - q * s
to, t = t, to - q * t
return ro, so, to
def modular_inverse(a, mod):
# https://en.wikipedia.org/wiki/Modular_multiplicative_inverse
g, s, t = egcd(a, mod)
assert g == 1, 'Value not invertible by modulus!'
return s % mod
class ECPoint:
#classmethod
def Int(cls, x):
return int(x)
#classmethod
def std_point(cls, name):
if name == 'secp256k1':
# https://en.bitcoin.it/wiki/Secp256k1
# https://www.secg.org/sec2-v2.pdf
p = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_FFFFFC2F
a = 0
b = 7
x = 0x79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798
y = 0x483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8
q = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141
else:
assert False
return ECPoint(x, y, a, b, p, q)
def __init__(self, x, y, A, B, N, q, *, prepare = True):
if prepare:
N = self.Int(N)
A, B, x, y, q = [self.Int(e) % N for e in [A, B, x, y, q]]
assert (4 * A ** 3 + 27 * B ** 2) % N != 0
assert (y ** 2 - x ** 3 - A * x - B) % N == 0, (
x, y, A, B, N, (y ** 2 - x ** 3 - A * x) % N)
assert N % 4 == 3
assert y == pow(x ** 3 + A * x + B, (N + 1) // 4, N)
self.A, self.B, self.N, self.x, self.y, self.q = A, B, N, x, y, q
def __add__(self, other):
A, N = self.A, self.N
Px, Py, Qx, Qy = self.x, self.y, other.x, other.y
if Px == Qx and Py == Qy:
s = ((Px * Px * 3 + A) * self.inv(Py * 2, N)) % N
else:
s = ((Py - Qy) * self.inv(Px - Qx, N)) % N
x = (s * s - Px - Qx) % N
y = (s * (Px - x) - Py) % N
return ECPoint(x, y, A, self.B, N, self.q, prepare = False)
def __rmul__(self, other):
other = self.Int(other - 1)
r = self
while True:
if other & 1:
r = r + self
if other == 1:
return r
other >>= 1
self = self + self
#classmethod
def inv(cls, a, n):
return modular_inverse(a, n)
def __repr__(self):
return str(dict(x = self.x, y = self.y, A = self.A,
B = self.B, N = self.N, q = self.q))
def __eq__(self, other):
for i, (a, b) in enumerate([
(self.x, other.x), (self.y, other.y), (self.A, other.A),
(self.B, other.B), (self.N, other.N), (self.q, other.q)]):
if a != b:
return False
return True
def test():
import random
bits = 256
P = random.randrange(1 << bits) * ECPoint.std_point('secp256k1')
k = random.randrange(1 << bits)
R = k * P
found_P = modular_inverse(k, R.q) * R
assert found_P == P
print(found_P)
if __name__ == '__main__':
test()
Output:
{
'x': 108051465657467150531748691374311160382608428790397210924352716318223953013557,
'y': 4462548165448905789984443302412298811224817997977472205419179335194291964455,
'A': 0,
'B': 7,
'N': 115792089237316195423570985008687907853269984665640564039457584007908834671663,
'q': 115792089237316195423570985008687907852837564279074904382605163141518161494337
}

Maxima - differentiating a piecewise function

Suppose you have a function defined by intervals, such as
f(x):=block(if x<0 then x^2 else x^3);
When we differentiate it with
diff(f(x),x);
we get
d/dx (if x<0 then x^2 else x^3)
whereas I'd like to get
(if x<0 then 2*x else 3*x^2)
Is there a way to obtain such result?
This may help in a simple case:
(%i1) f(x):= charfun(x<0)*x^2 + charfun(x>=0)*x^3$
(%i2) gradef(charfun(y), 0)$
(%i3) diff(f(x),x);
2
(%o3) 2 x charfun(x < 0) + 3 x charfun(x >= 0)
charfun, gradef
You can try also Pw.mac package from Richard Hennessy.
Here's a different approach using a simplification rule for "if" expressions. The unsolved part here is to detect discontinuities and generate delta functions for those locations. If you want to ignore those, you can define FOO to return 0. Note that I didn't attempt to implement the function discontinuities; that part is unsolved here. I can give it a try if there is interest.
(%i1) display2d : false $
(%i2) matchdeclare ([aa, bb, cc], all, xx, symbolp) $
(%i3) 'diff (if aa then bb else cc, xx) $
(%i4) tellsimpafter (''%, apply ("if", [aa, diff (bb, xx), true, diff (cc, xx)]) + FOO (aa, bb, cc, xx)) $
(%i5) FOO (a, b, c, x) := 'lsum ((ev (c, x = d) - ev (b, x = d)) * delta (d, x), d, discontinuities (a, x)) $
(%i6) diff (if x > 0 then x^2 else x^3, x);
(%o6) (if x > 0 then 2*x else 3*x^2)+'lsum((d^3-d^2)*delta(d,x),d,
discontinuities(x > 0,x))
Building on slitinov's answer I wrote this quite naive implementation for functions with more than two "pieces":
gradef(charfun(dummy),0)$
/* piecewise function definition */
itv: [[x<0],[x>=0,x<1], [x>=1]]; /* intervals */
fi: [ 1, x^2+1, 2*x ]; /* local functions */
/* creation of global function f and its derivative df */
f:0;
for i: 1 thru 3 do f:f+charfun(apply("and",itv[i]))*fi[i];
df:diff(f,x);
/* display of local functions and derivatives */
for i: 1 thru 3 do (
apply(assume,itv[i]),
newline(),
print(itv[i]),
print("f = ",ev(f)),
print("df = ",ev(df)),
apply(forget,itv[i])
);
plot2d([f,df],[x,-2,3],[y,-1,5],[style,[lines,4,3],[lines,2,2]]);

Resources