====================================================================== This file is part of the Yices SMT Solver. Copyright (C) 2017 SRI International. Yices is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Yices is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Yices. If not, see . ====================================================================== YICES LANGUAGE This is a summary of the commands and input language of the Yices 2 solver. 1) Lexical analysis ---------------- - comments start with ';' and extend to the end of the line ('\n' or EOF) - tokens are ( ) :: - are similar to strings in C: - they are delimited by " - the characters \n, \t are replaced by newline and tab - '\' followed by at most 3 octal digits is replaced by the character whose ASCII code is the octal number - in all other cases, '\' is replaced by (including if is newline) - newline cannot occur inside the string, unless preceded by '\' - are numbers in the format / or - also denote numbers in a floating-point format . or or . where is 'e' or 'E' - are bitvector constants in binary format 0b - are bitvector constants in hexadecimal format 0x - symbols start by anything that's not a digit, a space, or one of the characters ( ) ; : " if the first char is + or -, it must not be followed by a digit symbols end by a space of one of ( ) ; : " keywords -------- bool int real bitvector scalar tuple -> true false if ite = /= distinct or and not xor <=> => mk-tuple select tuple-update update forall exists lambda let + - * / ^ < <= > >= abs floor ceil div mod divides to-int mk-bv bv-add bv-sub bv-mul bv-neg bv-pow bv-not bv-and bv-or bv-xor bv-nand bv-nor bv-xnor bv-shift-left0 bv-shift-left1 bv-shift-right0 bv-shift-right1 bv-ashift-right bv-rotate-left bv-rotate-right bv-extract bv-concat bv-repeat bv-sign-extend bv-zero-extend bv-ge bv-gt bv-le bv-lt bv-sge bv-sgt bv-sle bv-slt bv-shl bv-lshr bv-ashr bv-div bv-rem bv-sdiv bv-srem bv-smod bv-redor bv-redand bv-comp bool-to-bv bit define-type define assert check push pop reset dump-context exit echo include show-model eval set-param show-param show-params show-stats reset-stats set-timeout help ef-solve export-to-dimacs show-implicant 2) Syntax ------ ::= ( define-type ) | ( define-type ) | ( define :: ) | ( define :: ) | ( assert ) | ( assert ) | ( exit ) | ( check ) | ( check-assuming * ) | ( ef-solve ) | ( push ) | ( pop ) | ( reset ) | ( show-model ) | ( show-reduced-model ) | ( show-implicant ) | ( show-unsat-core ) | ( show-unsat-assumptions ) | ( eval ) | ( echo ) | ( include ) | ( set-param ) | ( show-param ) | ( show-params ) | ( show-stats ) | ( reset-stats ) | ( set-timeout ) | ( show-timeout ) | ( export-to-dimacs ) | ( dump-context ) | ( help ) | ( help ) | ( help ) | EOS ::= | ( scalar ... ) ::= | ( tuple ... ) | ( -> ... ) | ( bitvector ) | int | bool | real ::= true | false | | | | | | ( forall ( ... ) ) | ( exists ( ... ) ) | ( lambda ( ... ) ) | ( let ( ... ) ) | ( update ( ... ) ) | ( ... ) ::= | ::= :: ::= ( ) ::= true | false | | ::= | ::= | ( not ) 3) Types ----- 3.1) The primitive types are: bool, int, real, and (bitvector k) where k is a positive integer. 3.2) A new uninterpreted type T can be declared using (define-type T) provided T is a fresh name (i.e., not already mapped to a type). 3.3) A new scalar type (i.e., a finite enumeration) can de defined using: (define-type (scalar ... )) must be a fresh type name ... must all be fresh term names and they must be distinct. There must be at list one element in the enumeration (i.e., n must be >= 1). This declaration introduces as a new type of n elements and also introduces n new constant ... , all of type . 3.4) A tuple type is written (tuple tau_1 ... tau_n) where tau_i's are types 3.5) A function type is written (-> tau_1 ... tau_n sigma) where the tau_i's and sigma are types. This is the type of functions of domain tau_1 x ... x tau_n and range sigma. There's no distinct array type constructor. Arrays are functions. 4) Built-in constants and functions -------------------------------- 4.1) ite is the if-then-else construct. if is a synonym for ite distinct takes are least 2 arguments. =, /= are strictly binary (unlike in SMT-LIB 1, where = can take more than two arguments). 4.2) true, false, or, and, not, xor, <=>, => are the usual boolean constants and functions. or, and, xor can take any number of arguments (provided there's at least one). <=> and => are binary operators. 4.3) the usual arithmetic operators are available. For example the linear expression 3x + y + 2 can be written (+ (* 3 x) y 2). The +, *, - operators can take any number of arguments (at least one), For the minus sign, Yices 2 (unlike Yices 1) follows the usual convention: (- x) means opposite of x (- x y z) means x - y - z, and could be written equivalently as (- x (+ y z)) Yices also includes division and exponentiation operators. Only division by constants is supported (provided the divisor is nonzero). (/ x 3) is fine (/ x 0) is an error (/ 1 x) is an error Exponentiation is written (^ ) the must be a non-negative integer constant. Arithmetic constraints include the usual inequality operators: <= < >= > (and the generic = and /= operations). 4.4) More arithmetic operations: (abs x) absolute value of x (floor x) largest integer less than or equal to x (ceil x) smallest integer more than or equal to x (div x k) integer division by a constant k (mod x k) modulo operation (divides k x) divisibility test (is-int x) integrality test Floor and ceiling satisfy the following constraints: (floor x) <= x < (floor x) + 1 (ceil x) - 1 <= x < (ceil x) For the division and modulo operations, the divider k must be a non-zero arithmetic constant. The division and remainder are defined as follows: (div x k) is an integer x = (div x k) * k + (mod x k) 0 <= (mod x k) < (abs k) Another way to look at this is: (div x k) = (floor (/ x k)) if k > 0 (div x k) = (ceil (/ x k)) if k < 0 This follows the SMT-LIB convention for the theory Ints, except that the Yices versions are not restricted to integers. Both div and mod are defined for any real x and non-zero constant k. For example, (div 1/3 1/6) is 2. The atom (divides k x) is true if x is an integer multiple of k, that is, we have: (divides k x) iff (exists (n::int) x = k * n) The divider k must be a constant (but it can be zero). If k is zero, (divides k x) is true iff x is zero. As in the div/mod operations, both k and x can be any real, not only integer. The atom (is-int x) it true if x is an integer. It can be defined using any of the following equivalences: (is-int x) iff (divides 1 x) (is-int x) iff (= x (floor x)) (is-int x) iff (= x (ceil x)) 4.5) tuple constructor: (mk-tuple ... ) with n>=1 projection: (select i) is the i-th component of the term . must have type (tuple tau_1 ... tau_n) and i must be between 1 and n tuple update: (tuple-update i ) is with the i-th component replaced by 4.6) function update: (update ( ... ) ) 4.7) bitvector functions: a) bitvector constant from an integer (mk-bv ) Note: value must be a non-negative integer and size must be a positive integer. b) bitvector arithmetic bv-add, bv-sub, bv-mul take one or more arguments, all arguments must have the same size (bv-neg x) = opposite of x in 2's complement arithmetic (bv-pow x k) = exponentiation (k must be a non-negative integer constant) c) bitwise logical operators (bv-not x) = bitwise negation of x bv-and, bv-or, bv-xor, bv-nand, bv-nor, bv-xnor: bitwise operators, all take one or more arguments of the same size note: (bv-xnor x y) is the same as (bv-not (bv-xor x y)). d) shift/rotate by a fixed constant (bv-shift-left0 x k): shift x by k bits to the left, padding with 0 (bv-shift-left1 x k): shift x by k bits to the left, padding with 1 (bv-shift-right0 x k): shift x by k bits to the right, padding with 0 (bv-shift-right1 x k): shift x by k bits to the right, padding with 1 (bv-ashift-right x k): arithmetic shift by k bits (bv-rotate-left x k): rotate x by k bits to the left (bv-rotate-right x k): rotate x by k bits to the right In all these shift/rotate operations, k must an integer be between 0 and the size of x. shift by a varying amount: in the following operations, x and y must be bitvectors of the same size (n bits) (bv-shl x y): shift x by k bits to the left, padding with 0 where k = value of bitvector y (bv-lshr x y): logical shift: shift x by k bits to the right (padding with 0) where k = value of bitvector y (bv-ashr x y): arithmetic shift: shift x by k bits to the right, padding with x's sign bit, where k = value of bitvector y. e) subvector extraction: (bv-extract i j x): extract bits j, j+1, .. i of x Requires 0 <= j <= i <= (size of x) - 1. f) bv-concat takes one or more arguments. Example: (bv-concat 0b000 0b111 0b00001) is the same as 0b00011100001 g) (bv-repeat x n) is n copies of x concatenated together. n must be > 0. h) (bv-sign-extend x n): add n times the sign bit to the left of x (n must be >= 0) (bv-zero-extend x n): add n times '0' to the left of x (n must be >= 0) i) unsigned bit-vector comparisons: (bv-ge x y): x >= y (bv-gt x y): x > y (bv-le x y): x <= y (bv-lt x y): x < y x and y are interpreted as non-negative integers (both must have the same size) j) signed bit-vector comparisons (bv-sge x y): x >= y (bv-sgt x y): x > y (bv-sle x y): x <= y (bv-slt x y): x < y x and y are interpreted as signed integers (in 2's complement representation) they must have the same size k) (bv-div x y): quotient in the unsigned division of x by y (bv-rem x y): remainder in the unsigned division of x by y x and y must have the same size (n bits) if y = 0, Yices uses the following convention: (bv-rem x 0) = x (bv-div x 0) = largest integer representable using n bits (i.e. 0b1111...1) (bv-sdiv x y): quotient in the signed division of x by y, with rounding to 0 (bv-srem x y): remainder in the signed division of x by y (also rounding to 0). x and y must have the same size if y = 0, Yices uses the following convention: (bv-srem x 0) = x (bv-sdiv x 0) = 0b00000...01 if x < 0 (bv-sdiv x 0) = 0b11111...11 if x >= 0 (bv-smod x y): remainder in the signed division of x by y, with rounding to minus infinity if y = 0, (bv-smod x 0) = x. l) (bv-redor x): this is the 1-bit vector [(or b_0 ... b_{n-1})] where b_i is bit i of x (bv-redand x): same thing for and (bv-comp x y): compute a 1-bit vector u such that u = 0b1 if x and y are equal u = 0b0 otherwise x and y must have the same size. m) Conversion between Boolean and bitvector terms (bool-to-bv b_1 ... b_n): build a bitvector from n Boolean terms the result is a bitvector of n bits equal to [b_1 .... b_n]: - b_1 = high-order bit - b_n = low-order bit (bit u i): extract the i-th bit of bitvector u (as a Boolean term) - if u has type (bitvector n) then i must be an integer constant such that 0 <= i <= n-1 - (bit u 0) = low-order bit of u - (bit u n-1) = high-order bit of u Examples: (bool-to-bv true false false) is 0b100 (bit 0b100 0) is false (bit 0b100 1) is false (bit 0b100 2) is true 5) Commands -------- (define-type name): create a new uninterpreted type called 'name' (define-type name ) : create a new type called 'name' equal to the (define name :: ): create a new uninterpreted constant (i.e., global variable) of the given called (define name :: ): create a new term called 'name' equal to After this definition, every occurrence of 'name' in any expression is replaced by . (assert ): add an assertion to the context (assert