-1

I tried to realize something in smtlib like a union in C:

union IntBoolType
{
    int i;
    boolean b;
} x;

My achievement so far:

(declare-datatypes (Int) ((IntPart INone (part (i Int)))))
(declare-datatypes (Bool) ((BoolPart BNone (part (b Bool)))))

(declare-datatypes () ((IntBoolType (mk (ipart (IntPart Int)) 
                                        (bpart (BoolPart Bool))))))

The idea is, that IntBoolType should contain either an int or (xor) a boolean value. To denote "None" I introduced the two fields on the sub-datatypes. I declared a couple of constants of type IntBoolType (ibt1 to ibt10) and now I wanted to define assertions to support these requirements:

(assert (distinct ibt1 ibt2 ibt3 ... ibt10)
(assert (xor (= (ipart ibt1) INone) (= (bpart ibt1) BNone)))

The second assertion is necessary, because otherwise I got one solution with INone and BNone. However, now z3 prints outputs which contains both integers and boolean values. Did I miss something? Is there a smarter way to encode this problem?

paubo147
  • 748
  • 4
  • 8
  • The type parameters Int and Bool below can be removed: (declare-datatypes () ((IntPart INone (part (i Int))))) (declare-datatypes () ((BoolPart BNone (part (b Bool))))) The standard declaration of option types in CVC4/Z3's datatype syntax is: (declare-datatypes (U) ((Option None (Some (some U))))) – Tim Jul 11 '14 at 04:27

1 Answers1

0

Backing up for a second, consider the corresponding ML type you have created.

type intpart = int option
type boolpart = bool option
type intbooltype = Mk of intpart * boolpart

It is always a pair of options. I am guessing you wanted is an either:

type ('a,'b) either = Left of 'a | Right of 'b

The way to write this in the datatypes extension that CVC4 and z3 support is:

(declare-datatypes (U T) ((Either (Left (left U))
                                  (Right (right T)))))

(Note that is not the same thing as a C union, but that is another story.)

Tim
  • 1,008
  • 5
  • 13
  • Yeah you are right. So there is no need to define a "None" type? I thought it must be easier, since most of the solvers are built on top of algebraic datatypes. So basically the "mk" was the error, since it creates a pair. If I omit the "mk", an "either is assumed, right? – paubo147 Jul 11 '14 at 07:28
  • You need "mk". It is the constructor in your example. The various parts of your example are: the "IntBoolType" is the name of the datatype sort (a 0-ary sort constructor), the datatype has 1 constructor "mk". This constructor takes two arguments with sorts (IntPart int) and (BoolPart Bool). The selection functions for these two parts are ipart and bpart. IntPart and BoolPart are sort constructors symbols applied to Int and Bool, but (IntPart Bool) is also a valid sort. – Tim Jul 12 '14 at 05:02