0
votes

This question is related to: Cyclic relation in Datalog using SMTLib for z3

I would like to reverse the problem described in the link above. I mean i want to detect the non existence of a cycle in a graph.

The proposed solution was:

(set-option :fixedpoint.engine datalog) 
(define-sort s () Int) 

(declare-rel edge (s s)) 
(declare-rel path (s s)) 

(declare-var a s) 
(declare-var b s) 
(declare-var c s) 

(rule (=> (edge a b) (path a b)) P-1)
(rule (=> (and (path a b) (path b c)) (path a c)) P-2)

(rule (edge 1 2) E-1)
(rule (edge 2 3) E-2)
(rule (edge 3 1) E-3)

(declare-rel cycle (s))
(rule (=> (path a a) (cycle a)))
(query cycle :print-answer true)

But my question is how can i get SAT when there is no cycle in the graph and UNSAT when there exists a cycle.

One suggestion (but that does not meet my need) is:

(set-option :fixedpoint.engine datalog) 
(define-sort s () Int) 

(declare-rel edge (s s)) 
(declare-rel path (s s)) 

(declare-var a s) 
(declare-var b s) 
(declare-var c s) 

(rule (=> (edge a b) (path a b)))
(rule (=> (and (path a b) (path b c)) (path a c)))

(rule (edge 1 2) r-1)
(rule (edge 2 3) r-2)
(rule (edge 3 1) r-3)


(assert (not (path a a)))

(check-sat)
(get-model)

which returns as result:

> z3 test.txt
sat
(model
  (define-fun a () Int
    0)
  (define-fun path ((x!0 Int) (x!1 Int)) Bool
    (ite (and (= x!0 0) (= x!1 0)) false
      false))
)

I don't understand why z3 assign 0 to the variables while i only have 1, 2 and 3 as vertices?

Another suggestion is :

(set-option :fixedpoint.engine datalog) 
(define-sort s () Int) 

(declare-rel edge (s s)) 
(declare-rel path (s s)) 

(declare-var a s) 
(declare-var b s) 
(declare-var c s) 

(rule (=> (edge a b) (path a b)))
(rule (=> (and (path a b) (path b c)) (path a c)))

(rule (edge 1 2) r-1)
(rule (edge 2 3) r-2)
(rule (edge 3 1) r-3)


(assert
         (=> (path a a)
            false
            )  

 )


(check-sat)
(get-model)

Which returns the result:

> z3 test2.txt
sat
(model
  (define-fun a () Int
    0)
  (define-fun path ((x!0 Int) (x!1 Int)) Bool
    (ite (and (= x!0 0) (= x!1 0)) false
      false))
)

Any idea to resolve this problem?

(Using Quantifiers will increase the complexity of problem, that's why i'm looking for some alternative solutions).

1

1 Answers

0
votes

I am not familiar with this part of z3, but in general, the result seems reasonable to me. Z3 is trying to find a model for your problem. You never stated that 1 2 3 are ALL the vertice, but only that they are some vertices. You can probably fix this by introducing a predicate for vertices and saying that anything else is not a vertex.

In the worst case you might need a Quantifier