0

I would like to express this problem in the SMTLib Format and evaluate it using Z3.

edge("som1","som3").
edge("som2","som4").
edge("som4","som1").
edge("som3","som4").
path(x,y) :- edge(x,y). % x and y are strings
path(x,z) :- edge(x,y), path(y,z).
:- path(x,y), path(y,x). %cyclic path.

My question is how to write the rule (or query) which detect the existence of a cycle in the relation path (this rule in basic datalog : :- path(x,y), path(y,x) ).

alias
  • 28,120
  • 2
  • 23
  • 40
Inzo. Geo
  • 47
  • 4
  • Did you review https://rise4fun.com/z3/tutorialcontent/fixedpoints? – alias Jul 09 '18 at 18:57
  • Yes, but in the link they illustrate the graph example using the binary type ((define-sort s () (_ BitVec 3)) but for me i want firstly use strings instead binary and also express the rule (or query) which detect the existence of a cycle in the relation path (this rule in basic datalog : :- path(x,y), path(y,x) ). – Inzo. Geo Jul 10 '18 at 09:09
  • It would be good to know where exactly you got stuck, i.e. what you tried so far. – Malte Schwerhoff Jul 10 '18 at 12:21
  • That's what i did: (set-option :fixedpoint.engine datalog) (define-sort s () (_ String 10)) (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 "som1" "som2")) (rule (edge "som2" "som3")) (rule (edge "som3" "som1")). The problem for me is how to write a rule which detect the existence of a cycle in the path relation. – Inzo. Geo Jul 10 '18 at 13:30
  • I mean : (this rule in basic datalog : :- path(x,y), path(y,x) ) which is equivalent to : ( false <-- path(x,y), path(y,x) ) – Inzo. Geo Jul 10 '18 at 13:36

1 Answers1

1

The tutorial Levent Erkok pointed out actually contains all the right information (I think). Knowing neither Datalog nor Z3's fixpoint features, I was still able to piece together the following:

(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)

Z3 4.8.0 nightly reports sat, indicating that there is a cycle, but unsat if any of the E-rules is removed.

I had to use ints instead of strings, though, since (my version of) Z3 aborts with the error Rule contains infinite sorts in rule P-1 if strings are used.

Malte Schwerhoff
  • 12,684
  • 4
  • 41
  • 71
  • Please how to get Z3 4.8.0, because Z3.7.1 is the last available version in https://github.com/Z3Prover/z3/releases for windows. This version returns the error : C:\Users\IEUser\Desktop>z3 stack.txt (error "query failed: Rule contains infinite sorts in rule P-1: path(#1,#0) :- edge(#1,#0). ") unknown – Inzo. Geo Jul 10 '18 at 15:04
  • It works now, Thank you, but in my problem the edges should be strings not Int. – Inzo. Geo Jul 10 '18 at 15:28
  • Malte's solution is as best as you'll get. Z3's DataLog engine has limitations in the types of variables you can use; in particular String's are just not supported in that domain. You'll have to do your mapping outside of z3. – alias Jul 10 '18 at 18:02
  • Not sure if I understand your question ... isn't a, admittedly rather cryptic, error message official enough? I you want to know details about why strings aren't (yet?) supported in combination with DataLog, you're probably better of filing an enhancement request on Z3's issue tracker. – Malte Schwerhoff Jul 12 '18 at 07:27
  • i get an answer from Mr. NikolajBjorner : There is no support for strings with the fixed point engines. The bddbddb format accept strings as names of elements of a finite domain, but these are not real strings, just names of constants. – Inzo. Geo Jul 13 '18 at 08:59
  • @Inzo.Geo Consider accepting an answer, or posting further details if your question hasn't been answered to your satisfaction. – Malte Schwerhoff Jul 17 '18 at 08:23
  • Good answer. But for my case i need to get the model (get-model) when there is no cycle (UNSAT response). – Inzo. Geo Jul 17 '18 at 09:41
  • In case of UNSAT there doesn't exist a model (hence not satisfiable). Maybe an unsatisfiable core is what you're looking for? https://stackoverflow.com/questions/18132243. Another hint on Stackoverflow best practices: don't contentiously add new requirements/constraints to a question. Keep questions are focused as possible, and open new questions instead, potentially linking back to previous, related questions. – Malte Schwerhoff Jul 17 '18 at 11:34
  • Get a look please : https://stackoverflow.com/questions/51543747/smtlib-format-for-z3-datalog-rule-elta-b-and-eltb-a-false – Inzo. Geo Jul 27 '18 at 09:29