/****************************************************************************** * Top contributors (to current version): * Mudathir Mohamed, Aina Niemetz, Andrew Reynolds * * This file is part of the cvc5 project. * * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS * in the top-level source directory and their institutional affiliations. * All rights reserved. See the file COPYING in the top-level source * directory for licensing information. * **************************************************************************** * * Black box testing of the Term class. */ package tests; import static io.github.cvc5.Kind.*; import static org.junit.jupiter.api.Assertions.*; import io.github.cvc5.*; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class TermTest { private TermManager d_tm; private Solver d_solver; @BeforeEach void setUp() { d_tm = new TermManager(); d_solver = new Solver(d_tm); } @AfterEach void tearDown() { Context.deletePointers(); } @Test void equalHash() { Sort uSort = d_tm.mkUninterpretedSort("u"); Term x = d_tm.mkVar(uSort, "x"); Term y = d_tm.mkVar(uSort, "y"); Term z = new Term(); assertTrue(x.equals(x)); assertFalse(x.equals(y)); assertFalse(x.equals(z)); assertEquals(x.hashCode(), x.hashCode()); assertNotEquals(x.hashCode(), y.hashCode()); assertNotEquals(x.hashCode(), z.hashCode()); } @Test void getId() { Term n = new Term(); assertThrows(CVC5ApiException.class, () -> n.getId()); Term x = d_tm.mkVar(d_tm.getIntegerSort(), "x"); assertDoesNotThrow(() -> x.getId()); Term y = x; assertEquals(x.getId(), y.getId()); Term z = d_tm.mkVar(d_tm.getIntegerSort(), "z"); assertNotEquals(x.getId(), z.getId()); } @Test void getKind() throws CVC5ApiException { Sort uSort = d_tm.mkUninterpretedSort("u"); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(uSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); Term n = new Term(); assertThrows(CVC5ApiException.class, () -> n.getKind()); Term x = d_tm.mkVar(uSort, "x"); assertDoesNotThrow(() -> x.getKind()); Term y = d_tm.mkVar(uSort, "y"); assertDoesNotThrow(() -> y.getKind()); Term f = d_tm.mkVar(funSort1, "f"); assertDoesNotThrow(() -> f.getKind()); Term p = d_tm.mkVar(funSort2, "p"); assertDoesNotThrow(() -> p.getKind()); Term zero = d_tm.mkInteger(0); assertDoesNotThrow(() -> zero.getKind()); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertDoesNotThrow(() -> f_x.getKind()); Term f_y = d_tm.mkTerm(APPLY_UF, f, y); assertDoesNotThrow(() -> f_y.getKind()); Term sum = d_tm.mkTerm(ADD, f_x, f_y); assertDoesNotThrow(() -> sum.getKind()); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.getKind()); Term p_f_y = d_tm.mkTerm(APPLY_UF, p, f_y); assertDoesNotThrow(() -> p_f_y.getKind()); // Sequence kinds do not exist internally, test that the API properly // converts them back. Sort seqSort = d_tm.mkSequenceSort(intSort); Term s = d_tm.mkConst(seqSort, "s"); Term ss = d_tm.mkTerm(SEQ_CONCAT, s, s); assertEquals(ss.getKind(), SEQ_CONCAT); } @Test void getSort() throws CVC5ApiException { Sort bvSort = d_tm.mkBitVectorSort(8); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(bvSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); Term n = new Term(); assertThrows(CVC5ApiException.class, () -> n.getSort()); Term x = d_tm.mkVar(bvSort, "x"); assertDoesNotThrow(() -> x.getSort()); assertEquals(x.getSort(), bvSort); Term y = d_tm.mkVar(bvSort, "y"); assertDoesNotThrow(() -> y.getSort()); assertEquals(y.getSort(), bvSort); Term f = d_tm.mkVar(funSort1, "f"); assertDoesNotThrow(() -> f.getSort()); assertEquals(f.getSort(), funSort1); Term p = d_tm.mkVar(funSort2, "p"); assertDoesNotThrow(() -> p.getSort()); assertEquals(p.getSort(), funSort2); Term zero = d_tm.mkInteger(0); assertDoesNotThrow(() -> zero.getSort()); assertEquals(zero.getSort(), intSort); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertDoesNotThrow(() -> f_x.getSort()); assertEquals(f_x.getSort(), intSort); Term f_y = d_tm.mkTerm(APPLY_UF, f, y); assertDoesNotThrow(() -> f_y.getSort()); assertEquals(f_y.getSort(), intSort); Term sum = d_tm.mkTerm(ADD, f_x, f_y); assertDoesNotThrow(() -> sum.getSort()); assertEquals(sum.getSort(), intSort); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.getSort()); assertEquals(p_0.getSort(), boolSort); Term p_f_y = d_tm.mkTerm(APPLY_UF, p, f_y); assertDoesNotThrow(() -> p_f_y.getSort()); assertEquals(p_f_y.getSort(), boolSort); } @Test void getOp() throws CVC5ApiException { Sort intsort = d_tm.getIntegerSort(); Sort bvsort = d_tm.mkBitVectorSort(8); Sort arrsort = d_tm.mkArraySort(bvsort, intsort); Sort funsort = d_tm.mkFunctionSort(intsort, bvsort); Term x = d_tm.mkConst(intsort, "x"); Term a = d_tm.mkConst(arrsort, "a"); Term b = d_tm.mkConst(bvsort, "b"); assertFalse(x.hasOp()); assertThrows(CVC5ApiException.class, () -> x.getOp()); Term ab = d_tm.mkTerm(SELECT, a, b); Op ext = d_tm.mkOp(BITVECTOR_EXTRACT, 4, 0); Term extb = d_tm.mkTerm(ext, b); assertTrue(ab.hasOp()); assertFalse(ab.getOp().isIndexed()); // can compare directly to a Kind (will invoke Op constructor) assertTrue(extb.hasOp()); assertTrue(extb.getOp().isIndexed()); assertEquals(extb.getOp(), ext); Op bit = d_tm.mkOp(BITVECTOR_BIT, 4); Term bitb = d_tm.mkTerm(bit, b); assertEquals(bitb.getKind(), BITVECTOR_BIT); assertTrue(bitb.hasOp()); assertEquals(bitb.getOp(), bit); assertTrue(bitb.getOp().isIndexed()); assertEquals(bit.getNumIndices(), 1); assertEquals(bit.get(0), d_tm.mkInteger(4)); Term f = d_tm.mkConst(funsort, "f"); Term fx = d_tm.mkTerm(APPLY_UF, f, x); assertFalse(f.hasOp()); assertThrows(CVC5ApiException.class, () -> f.getOp()); assertTrue(fx.hasOp()); List children = new ArrayList(); Iterator iterator = fx.iterator(); for (Term t : fx) { children.add(t); } // testing rebuild from op and children assertEquals(fx, d_tm.mkTerm(fx.getOp(), children.toArray(new Term[0]))); // Test Datatypes Ops Sort sort = d_tm.mkParamSort("T"); DatatypeDecl listDecl = d_tm.mkDatatypeDecl("paramlist", new Sort[] {sort}); DatatypeConstructorDecl cons = d_tm.mkDatatypeConstructorDecl("cons"); DatatypeConstructorDecl nil = d_tm.mkDatatypeConstructorDecl("nil"); cons.addSelector("head", sort); cons.addSelectorSelf("tail"); listDecl.addConstructor(cons); listDecl.addConstructor(nil); Sort listSort = d_tm.mkDatatypeSort(listDecl); Sort intListSort = listSort.instantiate(new Sort[] {d_tm.getIntegerSort()}); Term c = d_tm.mkConst(intListSort, "c"); Datatype list = listSort.getDatatype(); // list datatype constructor and selector operator terms Term consOpTerm = list.getConstructor("cons").getTerm(); Term nilOpTerm = list.getConstructor("nil").getTerm(); } @Test void hasGetSymbol() throws CVC5ApiException { Term n = new Term(); Term t = d_tm.mkBoolean(true); Term c = d_tm.mkConst(d_tm.getBooleanSort(), "|\\|"); assertThrows(CVC5ApiException.class, () -> n.hasSymbol()); assertFalse(t.hasSymbol()); assertTrue(c.hasSymbol()); assertThrows(CVC5ApiException.class, () -> n.getSymbol()); assertThrows(CVC5ApiException.class, () -> t.getSymbol()); assertEquals(c.getSymbol(), "|\\|"); } @Test void isNull() throws CVC5ApiException { Term x = new Term(); assertTrue(x.isNull()); x = d_tm.mkVar(d_tm.mkBitVectorSort(4), "x"); assertFalse(x.isNull()); } @Test void notTerm() throws CVC5ApiException { Sort bvSort = d_tm.mkBitVectorSort(8); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(bvSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); assertThrows(CVC5ApiException.class, () -> new Term().notTerm()); Term b = d_tm.mkTrue(); assertDoesNotThrow(() -> b.notTerm()); Term x = d_tm.mkVar(d_tm.mkBitVectorSort(8), "x"); assertThrows(CVC5ApiException.class, () -> x.notTerm()); Term f = d_tm.mkVar(funSort1, "f"); assertThrows(CVC5ApiException.class, () -> f.notTerm()); Term p = d_tm.mkVar(funSort2, "p"); assertThrows(CVC5ApiException.class, () -> p.notTerm()); Term zero = d_tm.mkInteger(0); assertThrows(CVC5ApiException.class, () -> zero.notTerm()); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertThrows(CVC5ApiException.class, () -> f_x.notTerm()); Term sum = d_tm.mkTerm(ADD, f_x, f_x); assertThrows(CVC5ApiException.class, () -> sum.notTerm()); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.notTerm()); Term p_f_x = d_tm.mkTerm(APPLY_UF, p, f_x); assertDoesNotThrow(() -> p_f_x.notTerm()); } @Test void andTerm() throws CVC5ApiException { Sort bvSort = d_tm.mkBitVectorSort(8); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(bvSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); Term b = d_tm.mkTrue(); assertThrows(CVC5ApiException.class, () -> new Term().andTerm(b)); assertThrows(CVC5ApiException.class, () -> b.andTerm(new Term())); assertDoesNotThrow(() -> b.andTerm(b)); Term x = d_tm.mkVar(d_tm.mkBitVectorSort(8), "x"); assertThrows(CVC5ApiException.class, () -> x.andTerm(b)); assertThrows(CVC5ApiException.class, () -> x.andTerm(x)); Term f = d_tm.mkVar(funSort1, "f"); assertThrows(CVC5ApiException.class, () -> f.andTerm(b)); assertThrows(CVC5ApiException.class, () -> f.andTerm(x)); assertThrows(CVC5ApiException.class, () -> f.andTerm(f)); Term p = d_tm.mkVar(funSort2, "p"); assertThrows(CVC5ApiException.class, () -> p.andTerm(b)); assertThrows(CVC5ApiException.class, () -> p.andTerm(x)); assertThrows(CVC5ApiException.class, () -> p.andTerm(f)); assertThrows(CVC5ApiException.class, () -> p.andTerm(p)); Term zero = d_tm.mkInteger(0); assertThrows(CVC5ApiException.class, () -> zero.andTerm(b)); assertThrows(CVC5ApiException.class, () -> zero.andTerm(x)); assertThrows(CVC5ApiException.class, () -> zero.andTerm(f)); assertThrows(CVC5ApiException.class, () -> zero.andTerm(p)); assertThrows(CVC5ApiException.class, () -> zero.andTerm(zero)); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertThrows(CVC5ApiException.class, () -> f_x.andTerm(b)); assertThrows(CVC5ApiException.class, () -> f_x.andTerm(x)); assertThrows(CVC5ApiException.class, () -> f_x.andTerm(f)); assertThrows(CVC5ApiException.class, () -> f_x.andTerm(p)); assertThrows(CVC5ApiException.class, () -> f_x.andTerm(zero)); assertThrows(CVC5ApiException.class, () -> f_x.andTerm(f_x)); Term sum = d_tm.mkTerm(ADD, f_x, f_x); assertThrows(CVC5ApiException.class, () -> sum.andTerm(b)); assertThrows(CVC5ApiException.class, () -> sum.andTerm(x)); assertThrows(CVC5ApiException.class, () -> sum.andTerm(f)); assertThrows(CVC5ApiException.class, () -> sum.andTerm(p)); assertThrows(CVC5ApiException.class, () -> sum.andTerm(zero)); assertThrows(CVC5ApiException.class, () -> sum.andTerm(f_x)); assertThrows(CVC5ApiException.class, () -> sum.andTerm(sum)); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.andTerm(b)); assertThrows(CVC5ApiException.class, () -> p_0.andTerm(x)); assertThrows(CVC5ApiException.class, () -> p_0.andTerm(f)); assertThrows(CVC5ApiException.class, () -> p_0.andTerm(p)); assertThrows(CVC5ApiException.class, () -> p_0.andTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_0.andTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_0.andTerm(sum)); assertDoesNotThrow(() -> p_0.andTerm(p_0)); Term p_f_x = d_tm.mkTerm(APPLY_UF, p, f_x); assertDoesNotThrow(() -> p_f_x.andTerm(b)); assertThrows(CVC5ApiException.class, () -> p_f_x.andTerm(x)); assertThrows(CVC5ApiException.class, () -> p_f_x.andTerm(f)); assertThrows(CVC5ApiException.class, () -> p_f_x.andTerm(p)); assertThrows(CVC5ApiException.class, () -> p_f_x.andTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_f_x.andTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_f_x.andTerm(sum)); assertDoesNotThrow(() -> p_f_x.andTerm(p_0)); assertDoesNotThrow(() -> p_f_x.andTerm(p_f_x)); } @Test void orTerm() throws CVC5ApiException { Sort bvSort = d_tm.mkBitVectorSort(8); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(bvSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); Term b = d_tm.mkTrue(); assertThrows(CVC5ApiException.class, () -> new Term().orTerm(b)); assertThrows(CVC5ApiException.class, () -> b.orTerm(new Term())); assertDoesNotThrow(() -> b.orTerm(b)); Term x = d_tm.mkVar(d_tm.mkBitVectorSort(8), "x"); assertThrows(CVC5ApiException.class, () -> x.orTerm(b)); assertThrows(CVC5ApiException.class, () -> x.orTerm(x)); Term f = d_tm.mkVar(funSort1, "f"); assertThrows(CVC5ApiException.class, () -> f.orTerm(b)); assertThrows(CVC5ApiException.class, () -> f.orTerm(x)); assertThrows(CVC5ApiException.class, () -> f.orTerm(f)); Term p = d_tm.mkVar(funSort2, "p"); assertThrows(CVC5ApiException.class, () -> p.orTerm(b)); assertThrows(CVC5ApiException.class, () -> p.orTerm(x)); assertThrows(CVC5ApiException.class, () -> p.orTerm(f)); assertThrows(CVC5ApiException.class, () -> p.orTerm(p)); Term zero = d_tm.mkInteger(0); assertThrows(CVC5ApiException.class, () -> zero.orTerm(b)); assertThrows(CVC5ApiException.class, () -> zero.orTerm(x)); assertThrows(CVC5ApiException.class, () -> zero.orTerm(f)); assertThrows(CVC5ApiException.class, () -> zero.orTerm(p)); assertThrows(CVC5ApiException.class, () -> zero.orTerm(zero)); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertThrows(CVC5ApiException.class, () -> f_x.orTerm(b)); assertThrows(CVC5ApiException.class, () -> f_x.orTerm(x)); assertThrows(CVC5ApiException.class, () -> f_x.orTerm(f)); assertThrows(CVC5ApiException.class, () -> f_x.orTerm(p)); assertThrows(CVC5ApiException.class, () -> f_x.orTerm(zero)); assertThrows(CVC5ApiException.class, () -> f_x.orTerm(f_x)); Term sum = d_tm.mkTerm(ADD, f_x, f_x); assertThrows(CVC5ApiException.class, () -> sum.orTerm(b)); assertThrows(CVC5ApiException.class, () -> sum.orTerm(x)); assertThrows(CVC5ApiException.class, () -> sum.orTerm(f)); assertThrows(CVC5ApiException.class, () -> sum.orTerm(p)); assertThrows(CVC5ApiException.class, () -> sum.orTerm(zero)); assertThrows(CVC5ApiException.class, () -> sum.orTerm(f_x)); assertThrows(CVC5ApiException.class, () -> sum.orTerm(sum)); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.orTerm(b)); assertThrows(CVC5ApiException.class, () -> p_0.orTerm(x)); assertThrows(CVC5ApiException.class, () -> p_0.orTerm(f)); assertThrows(CVC5ApiException.class, () -> p_0.orTerm(p)); assertThrows(CVC5ApiException.class, () -> p_0.orTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_0.orTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_0.orTerm(sum)); assertDoesNotThrow(() -> p_0.orTerm(p_0)); Term p_f_x = d_tm.mkTerm(APPLY_UF, p, f_x); assertDoesNotThrow(() -> p_f_x.orTerm(b)); assertThrows(CVC5ApiException.class, () -> p_f_x.orTerm(x)); assertThrows(CVC5ApiException.class, () -> p_f_x.orTerm(f)); assertThrows(CVC5ApiException.class, () -> p_f_x.orTerm(p)); assertThrows(CVC5ApiException.class, () -> p_f_x.orTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_f_x.orTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_f_x.orTerm(sum)); assertDoesNotThrow(() -> p_f_x.orTerm(p_0)); assertDoesNotThrow(() -> p_f_x.orTerm(p_f_x)); } @Test void xorTerm() throws CVC5ApiException { Sort bvSort = d_tm.mkBitVectorSort(8); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(bvSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); Term b = d_tm.mkTrue(); assertThrows(CVC5ApiException.class, () -> new Term().xorTerm(b)); assertThrows(CVC5ApiException.class, () -> b.xorTerm(new Term())); assertDoesNotThrow(() -> b.xorTerm(b)); Term x = d_tm.mkVar(d_tm.mkBitVectorSort(8), "x"); assertThrows(CVC5ApiException.class, () -> x.xorTerm(b)); assertThrows(CVC5ApiException.class, () -> x.xorTerm(x)); Term f = d_tm.mkVar(funSort1, "f"); assertThrows(CVC5ApiException.class, () -> f.xorTerm(b)); assertThrows(CVC5ApiException.class, () -> f.xorTerm(x)); assertThrows(CVC5ApiException.class, () -> f.xorTerm(f)); Term p = d_tm.mkVar(funSort2, "p"); assertThrows(CVC5ApiException.class, () -> p.xorTerm(b)); assertThrows(CVC5ApiException.class, () -> p.xorTerm(x)); assertThrows(CVC5ApiException.class, () -> p.xorTerm(f)); assertThrows(CVC5ApiException.class, () -> p.xorTerm(p)); Term zero = d_tm.mkInteger(0); assertThrows(CVC5ApiException.class, () -> zero.xorTerm(b)); assertThrows(CVC5ApiException.class, () -> zero.xorTerm(x)); assertThrows(CVC5ApiException.class, () -> zero.xorTerm(f)); assertThrows(CVC5ApiException.class, () -> zero.xorTerm(p)); assertThrows(CVC5ApiException.class, () -> zero.xorTerm(zero)); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertThrows(CVC5ApiException.class, () -> f_x.xorTerm(b)); assertThrows(CVC5ApiException.class, () -> f_x.xorTerm(x)); assertThrows(CVC5ApiException.class, () -> f_x.xorTerm(f)); assertThrows(CVC5ApiException.class, () -> f_x.xorTerm(p)); assertThrows(CVC5ApiException.class, () -> f_x.xorTerm(zero)); assertThrows(CVC5ApiException.class, () -> f_x.xorTerm(f_x)); Term sum = d_tm.mkTerm(ADD, f_x, f_x); assertThrows(CVC5ApiException.class, () -> sum.xorTerm(b)); assertThrows(CVC5ApiException.class, () -> sum.xorTerm(x)); assertThrows(CVC5ApiException.class, () -> sum.xorTerm(f)); assertThrows(CVC5ApiException.class, () -> sum.xorTerm(p)); assertThrows(CVC5ApiException.class, () -> sum.xorTerm(zero)); assertThrows(CVC5ApiException.class, () -> sum.xorTerm(f_x)); assertThrows(CVC5ApiException.class, () -> sum.xorTerm(sum)); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.xorTerm(b)); assertThrows(CVC5ApiException.class, () -> p_0.xorTerm(x)); assertThrows(CVC5ApiException.class, () -> p_0.xorTerm(f)); assertThrows(CVC5ApiException.class, () -> p_0.xorTerm(p)); assertThrows(CVC5ApiException.class, () -> p_0.xorTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_0.xorTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_0.xorTerm(sum)); assertDoesNotThrow(() -> p_0.xorTerm(p_0)); Term p_f_x = d_tm.mkTerm(APPLY_UF, p, f_x); assertDoesNotThrow(() -> p_f_x.xorTerm(b)); assertThrows(CVC5ApiException.class, () -> p_f_x.xorTerm(x)); assertThrows(CVC5ApiException.class, () -> p_f_x.xorTerm(f)); assertThrows(CVC5ApiException.class, () -> p_f_x.xorTerm(p)); assertThrows(CVC5ApiException.class, () -> p_f_x.xorTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_f_x.xorTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_f_x.xorTerm(sum)); assertDoesNotThrow(() -> p_f_x.xorTerm(p_0)); assertDoesNotThrow(() -> p_f_x.xorTerm(p_f_x)); } @Test void eqTerm() throws CVC5ApiException { Sort bvSort = d_tm.mkBitVectorSort(8); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(bvSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); Term b = d_tm.mkTrue(); assertThrows(CVC5ApiException.class, () -> new Term().eqTerm(b)); assertThrows(CVC5ApiException.class, () -> b.eqTerm(new Term())); assertDoesNotThrow(() -> b.eqTerm(b)); Term x = d_tm.mkVar(d_tm.mkBitVectorSort(8), "x"); assertThrows(CVC5ApiException.class, () -> x.eqTerm(b)); assertDoesNotThrow(() -> x.eqTerm(x)); Term f = d_tm.mkVar(funSort1, "f"); assertThrows(CVC5ApiException.class, () -> f.eqTerm(b)); assertThrows(CVC5ApiException.class, () -> f.eqTerm(x)); assertDoesNotThrow(() -> f.eqTerm(f)); Term p = d_tm.mkVar(funSort2, "p"); assertThrows(CVC5ApiException.class, () -> p.eqTerm(b)); assertThrows(CVC5ApiException.class, () -> p.eqTerm(x)); assertThrows(CVC5ApiException.class, () -> p.eqTerm(f)); assertDoesNotThrow(() -> p.eqTerm(p)); Term zero = d_tm.mkInteger(0); assertThrows(CVC5ApiException.class, () -> zero.eqTerm(b)); assertThrows(CVC5ApiException.class, () -> zero.eqTerm(x)); assertThrows(CVC5ApiException.class, () -> zero.eqTerm(f)); assertThrows(CVC5ApiException.class, () -> zero.eqTerm(p)); assertDoesNotThrow(() -> zero.eqTerm(zero)); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertThrows(CVC5ApiException.class, () -> f_x.eqTerm(b)); assertThrows(CVC5ApiException.class, () -> f_x.eqTerm(x)); assertThrows(CVC5ApiException.class, () -> f_x.eqTerm(f)); assertThrows(CVC5ApiException.class, () -> f_x.eqTerm(p)); assertDoesNotThrow(() -> f_x.eqTerm(zero)); assertDoesNotThrow(() -> f_x.eqTerm(f_x)); Term sum = d_tm.mkTerm(ADD, f_x, f_x); assertThrows(CVC5ApiException.class, () -> sum.eqTerm(b)); assertThrows(CVC5ApiException.class, () -> sum.eqTerm(x)); assertThrows(CVC5ApiException.class, () -> sum.eqTerm(f)); assertThrows(CVC5ApiException.class, () -> sum.eqTerm(p)); assertDoesNotThrow(() -> sum.eqTerm(zero)); assertDoesNotThrow(() -> sum.eqTerm(f_x)); assertDoesNotThrow(() -> sum.eqTerm(sum)); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.eqTerm(b)); assertThrows(CVC5ApiException.class, () -> p_0.eqTerm(x)); assertThrows(CVC5ApiException.class, () -> p_0.eqTerm(f)); assertThrows(CVC5ApiException.class, () -> p_0.eqTerm(p)); assertThrows(CVC5ApiException.class, () -> p_0.eqTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_0.eqTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_0.eqTerm(sum)); assertDoesNotThrow(() -> p_0.eqTerm(p_0)); Term p_f_x = d_tm.mkTerm(APPLY_UF, p, f_x); assertDoesNotThrow(() -> p_f_x.eqTerm(b)); assertThrows(CVC5ApiException.class, () -> p_f_x.eqTerm(x)); assertThrows(CVC5ApiException.class, () -> p_f_x.eqTerm(f)); assertThrows(CVC5ApiException.class, () -> p_f_x.eqTerm(p)); assertThrows(CVC5ApiException.class, () -> p_f_x.eqTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_f_x.eqTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_f_x.eqTerm(sum)); assertDoesNotThrow(() -> p_f_x.eqTerm(p_0)); assertDoesNotThrow(() -> p_f_x.eqTerm(p_f_x)); } @Test void impTerm() throws CVC5ApiException { Sort bvSort = d_tm.mkBitVectorSort(8); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(bvSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); Term b = d_tm.mkTrue(); assertThrows(CVC5ApiException.class, () -> new Term().impTerm(b)); assertThrows(CVC5ApiException.class, () -> b.impTerm(new Term())); assertDoesNotThrow(() -> b.impTerm(b)); Term x = d_tm.mkVar(d_tm.mkBitVectorSort(8), "x"); assertThrows(CVC5ApiException.class, () -> x.impTerm(b)); assertThrows(CVC5ApiException.class, () -> x.impTerm(x)); Term f = d_tm.mkVar(funSort1, "f"); assertThrows(CVC5ApiException.class, () -> f.impTerm(b)); assertThrows(CVC5ApiException.class, () -> f.impTerm(x)); assertThrows(CVC5ApiException.class, () -> f.impTerm(f)); Term p = d_tm.mkVar(funSort2, "p"); assertThrows(CVC5ApiException.class, () -> p.impTerm(b)); assertThrows(CVC5ApiException.class, () -> p.impTerm(x)); assertThrows(CVC5ApiException.class, () -> p.impTerm(f)); assertThrows(CVC5ApiException.class, () -> p.impTerm(p)); Term zero = d_tm.mkInteger(0); assertThrows(CVC5ApiException.class, () -> zero.impTerm(b)); assertThrows(CVC5ApiException.class, () -> zero.impTerm(x)); assertThrows(CVC5ApiException.class, () -> zero.impTerm(f)); assertThrows(CVC5ApiException.class, () -> zero.impTerm(p)); assertThrows(CVC5ApiException.class, () -> zero.impTerm(zero)); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertThrows(CVC5ApiException.class, () -> f_x.impTerm(b)); assertThrows(CVC5ApiException.class, () -> f_x.impTerm(x)); assertThrows(CVC5ApiException.class, () -> f_x.impTerm(f)); assertThrows(CVC5ApiException.class, () -> f_x.impTerm(p)); assertThrows(CVC5ApiException.class, () -> f_x.impTerm(zero)); assertThrows(CVC5ApiException.class, () -> f_x.impTerm(f_x)); Term sum = d_tm.mkTerm(ADD, f_x, f_x); assertThrows(CVC5ApiException.class, () -> sum.impTerm(b)); assertThrows(CVC5ApiException.class, () -> sum.impTerm(x)); assertThrows(CVC5ApiException.class, () -> sum.impTerm(f)); assertThrows(CVC5ApiException.class, () -> sum.impTerm(p)); assertThrows(CVC5ApiException.class, () -> sum.impTerm(zero)); assertThrows(CVC5ApiException.class, () -> sum.impTerm(f_x)); assertThrows(CVC5ApiException.class, () -> sum.impTerm(sum)); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.impTerm(b)); assertThrows(CVC5ApiException.class, () -> p_0.impTerm(x)); assertThrows(CVC5ApiException.class, () -> p_0.impTerm(f)); assertThrows(CVC5ApiException.class, () -> p_0.impTerm(p)); assertThrows(CVC5ApiException.class, () -> p_0.impTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_0.impTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_0.impTerm(sum)); assertDoesNotThrow(() -> p_0.impTerm(p_0)); Term p_f_x = d_tm.mkTerm(APPLY_UF, p, f_x); assertDoesNotThrow(() -> p_f_x.impTerm(b)); assertThrows(CVC5ApiException.class, () -> p_f_x.impTerm(x)); assertThrows(CVC5ApiException.class, () -> p_f_x.impTerm(f)); assertThrows(CVC5ApiException.class, () -> p_f_x.impTerm(p)); assertThrows(CVC5ApiException.class, () -> p_f_x.impTerm(zero)); assertThrows(CVC5ApiException.class, () -> p_f_x.impTerm(f_x)); assertThrows(CVC5ApiException.class, () -> p_f_x.impTerm(sum)); assertDoesNotThrow(() -> p_f_x.impTerm(p_0)); assertDoesNotThrow(() -> p_f_x.impTerm(p_f_x)); } @Test void iteTerm() throws CVC5ApiException { Sort bvSort = d_tm.mkBitVectorSort(8); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort funSort1 = d_tm.mkFunctionSort(bvSort, intSort); Sort funSort2 = d_tm.mkFunctionSort(intSort, boolSort); Term b = d_tm.mkTrue(); assertThrows(CVC5ApiException.class, () -> new Term().iteTerm(b, b)); assertThrows(CVC5ApiException.class, () -> b.iteTerm(new Term(), b)); assertThrows(CVC5ApiException.class, () -> b.iteTerm(b, new Term())); assertDoesNotThrow(() -> b.iteTerm(b, b)); Term x = d_tm.mkVar(d_tm.mkBitVectorSort(8), "x"); assertDoesNotThrow(() -> b.iteTerm(x, x)); assertDoesNotThrow(() -> b.iteTerm(b, b)); assertThrows(CVC5ApiException.class, () -> b.iteTerm(x, b)); assertThrows(CVC5ApiException.class, () -> x.iteTerm(x, x)); assertThrows(CVC5ApiException.class, () -> x.iteTerm(x, b)); Term f = d_tm.mkVar(funSort1, "f"); assertThrows(CVC5ApiException.class, () -> f.iteTerm(b, b)); assertThrows(CVC5ApiException.class, () -> x.iteTerm(b, x)); Term p = d_tm.mkVar(funSort2, "p"); assertThrows(CVC5ApiException.class, () -> p.iteTerm(b, b)); assertThrows(CVC5ApiException.class, () -> p.iteTerm(x, b)); Term zero = d_tm.mkInteger(0); assertThrows(CVC5ApiException.class, () -> zero.iteTerm(x, x)); assertThrows(CVC5ApiException.class, () -> zero.iteTerm(x, b)); Term f_x = d_tm.mkTerm(APPLY_UF, f, x); assertThrows(CVC5ApiException.class, () -> f_x.iteTerm(b, b)); assertThrows(CVC5ApiException.class, () -> f_x.iteTerm(b, x)); Term sum = d_tm.mkTerm(ADD, f_x, f_x); assertThrows(CVC5ApiException.class, () -> sum.iteTerm(x, x)); assertThrows(CVC5ApiException.class, () -> sum.iteTerm(b, x)); Term p_0 = d_tm.mkTerm(APPLY_UF, p, zero); assertDoesNotThrow(() -> p_0.iteTerm(b, b)); assertDoesNotThrow(() -> p_0.iteTerm(x, x)); assertThrows(CVC5ApiException.class, () -> p_0.iteTerm(x, b)); Term p_f_x = d_tm.mkTerm(APPLY_UF, p, f_x); assertDoesNotThrow(() -> p_f_x.iteTerm(b, b)); assertDoesNotThrow(() -> p_f_x.iteTerm(x, x)); assertThrows(CVC5ApiException.class, () -> p_f_x.iteTerm(x, b)); } @Test void termAssignment() { Term t1 = d_tm.mkInteger(1); Term t2 = t1; t2 = d_tm.mkInteger(2); assertEquals(t1, d_tm.mkInteger(1)); } @Test void termCompare() { Term t1 = d_tm.mkInteger(1); Term t2 = d_tm.mkTerm(ADD, d_tm.mkInteger(2), d_tm.mkInteger(2)); Term t3 = d_tm.mkTerm(ADD, d_tm.mkInteger(2), d_tm.mkInteger(2)); assertTrue(t2.compareTo(t3) >= 0); assertTrue(t2.compareTo(t3) <= 0); assertTrue((t1.compareTo(t2) > 0) != (t1.compareTo(t2) < 0)); assertTrue((t1.compareTo(t2) > 0 || t1.equals(t2)) == (t1.compareTo(t2) >= 0)); } @Test void termChildren() throws CVC5ApiException { // simple term 2+3 Term two = d_tm.mkInteger(2); Term t1 = d_tm.mkTerm(ADD, two, d_tm.mkInteger(3)); assertEquals(t1.getChild(0), two); assertEquals(t1.getNumChildren(), 2); Term tnull = new Term(); assertThrows(CVC5ApiException.class, () -> tnull.getNumChildren()); // apply term f(2) Sort intSort = d_tm.getIntegerSort(); Sort fsort = d_tm.mkFunctionSort(intSort, intSort); Term f = d_tm.mkConst(fsort, "f"); Term t2 = d_tm.mkTerm(APPLY_UF, f, two); // due to our higher-order view of terms, we treat f as a child of APPLY_UF assertEquals(t2.getNumChildren(), 2); assertEquals(t2.getChild(0), f); assertEquals(t2.getChild(1), two); assertThrows(CVC5ApiException.class, () -> tnull.getChild(0)); } @Test void getIntegerValue() throws CVC5ApiException { Term int1 = d_tm.mkInteger("-18446744073709551616"); Term int2 = d_tm.mkInteger("-18446744073709551615"); Term int3 = d_tm.mkInteger("-4294967296"); Term int4 = d_tm.mkInteger("-4294967295"); Term int5 = d_tm.mkInteger("-10"); Term int6 = d_tm.mkInteger("0"); Term int7 = d_tm.mkInteger("10"); Term int8 = d_tm.mkInteger("4294967295"); Term int9 = d_tm.mkInteger("4294967296"); Term int10 = d_tm.mkInteger("18446744073709551615"); Term int11 = d_tm.mkInteger("18446744073709551616"); Term int12 = d_tm.mkInteger("-0"); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("")); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("-")); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("-1-")); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("0.0")); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("-0.1")); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("012")); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("0000")); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("-01")); assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger("-00")); assertTrue(int1.isIntegerValue()); assertEquals(int1.getIntegerValue().toString(), "-18446744073709551616"); assertEquals(int1.getRealOrIntegerValueSign(), -1); assertTrue(int2.isIntegerValue()); assertEquals(int2.getIntegerValue().toString(), "-18446744073709551615"); assertTrue(int3.isIntegerValue()); assertEquals(int3.getIntegerValue().longValue(), -4294967296L); assertEquals(int3.getIntegerValue().toString(), "-4294967296"); assertTrue(int4.isIntegerValue()); assertEquals(int4.getIntegerValue().longValue(), -4294967295L); assertEquals(int4.getIntegerValue().toString(), "-4294967295"); assertTrue(int5.isIntegerValue()); assertEquals(int5.getIntegerValue().intValue(), -10); assertEquals(int5.getIntegerValue().intValue(), -10); assertEquals(int5.getIntegerValue().toString(), "-10"); assertTrue(int6.isIntegerValue()); assertEquals(int6.getIntegerValue().intValue(), 0); assertEquals(int6.getIntegerValue().intValue(), 0); assertEquals(int6.getIntegerValue().toString(), "0"); assertEquals(int6.getRealOrIntegerValueSign(), 0); assertTrue(int7.isIntegerValue()); assertEquals(int7.getIntegerValue().intValue(), 10); assertEquals(int7.getIntegerValue().intValue(), 10); assertEquals(int7.getIntegerValue().toString(), "10"); assertEquals(int7.getRealOrIntegerValueSign(), 1); assertTrue(int8.isIntegerValue()); assertEquals(int8.getIntegerValue().longValue(), 4294967295L); assertEquals(int8.getIntegerValue().toString(), "4294967295"); assertTrue(int9.isIntegerValue()); assertEquals(int9.getIntegerValue().longValue(), 4294967296L); assertEquals(int9.getIntegerValue().toString(), "4294967296"); assertTrue(int10.isIntegerValue()); assertEquals(int10.getIntegerValue().toString(), "18446744073709551615"); assertTrue(int11.isIntegerValue()); assertEquals(int11.getIntegerValue().toString(), "18446744073709551616"); } @Test void getString() { Term s1 = d_tm.mkString("abcde"); assertTrue(s1.isStringValue()); assertEquals(s1.getStringValue(), "abcde"); Term s2 = d_tm.mkString("\\u{200cb}", true); assertEquals(s2.getStringValue(), new String(Character.toChars(0x200cb))); } @Test void getReal() throws CVC5ApiException { Term real1 = d_tm.mkReal("0"); Term real2 = d_tm.mkReal(".0"); Term real3 = d_tm.mkReal("-17"); Term real4 = d_tm.mkReal("-3/5"); Term real5 = d_tm.mkReal("12.7"); Term real6 = d_tm.mkReal("1/4294967297"); Term real7 = d_tm.mkReal("4294967297"); Term real8 = d_tm.mkReal("1/18446744073709551617"); Term real9 = d_tm.mkReal("18446744073709551617"); Term real10 = d_tm.mkReal("2343.2343"); assertTrue(real1.isRealValue()); assertTrue(real2.isRealValue()); assertTrue(real3.isRealValue()); assertTrue(real4.isRealValue()); assertTrue(real5.isRealValue()); assertTrue(real6.isRealValue()); assertTrue(real7.isRealValue()); assertTrue(real8.isRealValue()); assertTrue(real9.isRealValue()); assertTrue(real10.isRealValue()); assertEquals("0/1", Utils.getRational(real1.getRealValue())); assertEquals("0/1", Utils.getRational(real2.getRealValue())); assertEquals("-17/1", Utils.getRational(real3.getRealValue())); assertEquals("-3/5", Utils.getRational(real4.getRealValue())); assertEquals("127/10", Utils.getRational(real5.getRealValue())); assertEquals("1/4294967297", Utils.getRational(real6.getRealValue())); assertEquals("4294967297/1", Utils.getRational(real7.getRealValue())); assertEquals("1/18446744073709551617", Utils.getRational(real8.getRealValue())); assertEquals("18446744073709551617/1", Utils.getRational(real9.getRealValue())); assertEquals("23432343/10000", Utils.getRational(real10.getRealValue())); assertThrows(CVC5ApiException.class, () -> d_tm.mkReal("1/0")); assertThrows(CVC5ApiException.class, () -> d_tm.mkReal("2/0000")); } @Test void getConstArrayBase() { Sort intsort = d_tm.getIntegerSort(); Sort arrsort = d_tm.mkArraySort(intsort, intsort); Term one = d_tm.mkInteger(1); Term constarr = d_tm.mkConstArray(arrsort, one); assertTrue(constarr.isConstArray()); assertEquals(one, constarr.getConstArrayBase()); Term a = d_tm.mkConst(arrsort, "a"); assertThrows(CVC5ApiException.class, () -> a.getConstArrayBase()); assertThrows(CVC5ApiException.class, () -> one.getConstArrayBase()); } @Test void getBoolean() { Term b1 = d_tm.mkBoolean(true); Term b2 = d_tm.mkBoolean(false); assertTrue(b1.isBooleanValue()); assertTrue(b2.isBooleanValue()); assertTrue(b1.getBooleanValue()); assertFalse(b2.getBooleanValue()); } @Test void getBitVector() throws CVC5ApiException { Term b1 = d_tm.mkBitVector(8, 15); Term b2 = d_tm.mkBitVector(8, "00001111", 2); Term b3 = d_tm.mkBitVector(8, "15", 10); Term b4 = d_tm.mkBitVector(8, "0f", 16); Term b5 = d_tm.mkBitVector(9, "00001111", 2); Term b6 = d_tm.mkBitVector(9, "15", 10); Term b7 = d_tm.mkBitVector(9, "0f", 16); assertTrue(b1.isBitVectorValue()); assertTrue(b2.isBitVectorValue()); assertTrue(b3.isBitVectorValue()); assertTrue(b4.isBitVectorValue()); assertTrue(b5.isBitVectorValue()); assertTrue(b6.isBitVectorValue()); assertTrue(b7.isBitVectorValue()); assertEquals("00001111", b1.getBitVectorValue(2)); assertEquals("15", b1.getBitVectorValue(10)); assertEquals("f", b1.getBitVectorValue(16)); assertEquals("00001111", b2.getBitVectorValue(2)); assertEquals("15", b2.getBitVectorValue(10)); assertEquals("f", b2.getBitVectorValue(16)); assertEquals("00001111", b3.getBitVectorValue(2)); assertEquals("15", b3.getBitVectorValue(10)); assertEquals("f", b3.getBitVectorValue(16)); assertEquals("00001111", b4.getBitVectorValue(2)); assertEquals("15", b4.getBitVectorValue(10)); assertEquals("f", b4.getBitVectorValue(16)); assertEquals("000001111", b5.getBitVectorValue(2)); assertEquals("15", b5.getBitVectorValue(10)); assertEquals("f", b5.getBitVectorValue(16)); assertEquals("000001111", b6.getBitVectorValue(2)); assertEquals("15", b6.getBitVectorValue(10)); assertEquals("f", b6.getBitVectorValue(16)); assertEquals("000001111", b7.getBitVectorValue(2)); assertEquals("15", b7.getBitVectorValue(10)); assertEquals("f", b7.getBitVectorValue(16)); } @Test void getUninterpretedSortValue() throws CVC5ApiException { d_solver.setOption("produce-models", "true"); Sort uSort = d_tm.mkUninterpretedSort("u"); Term x = d_tm.mkConst(uSort, "x"); Term y = d_tm.mkConst(uSort, "y"); d_solver.assertFormula(d_tm.mkTerm(EQUAL, x, y)); assertTrue(d_solver.checkSat().isSat()); Term vx = d_solver.getValue(x); Term vy = d_solver.getValue(y); assertEquals(vx.isUninterpretedSortValue(), vy.isUninterpretedSortValue()); assertDoesNotThrow(() -> vx.getUninterpretedSortValue()); assertDoesNotThrow(() -> vy.getUninterpretedSortValue()); } @Test void isRoundingModeValue() throws CVC5ApiException { assertFalse(d_tm.mkInteger(15).isRoundingModeValue()); assertTrue(d_tm.mkRoundingMode(RoundingMode.ROUND_NEAREST_TIES_TO_EVEN).isRoundingModeValue()); assertFalse(d_tm.mkConst(d_tm.getRoundingModeSort()).isRoundingModeValue()); } @Test void getRoundingModeValue() throws CVC5ApiException { assertThrows(CVC5ApiException.class, () -> d_tm.mkInteger(15).getRoundingModeValue()); assertEquals( d_tm.mkRoundingMode(RoundingMode.ROUND_NEAREST_TIES_TO_EVEN).getRoundingModeValue(), RoundingMode.ROUND_NEAREST_TIES_TO_EVEN); assertEquals(d_tm.mkRoundingMode(RoundingMode.ROUND_TOWARD_POSITIVE).getRoundingModeValue(), RoundingMode.ROUND_TOWARD_POSITIVE); assertEquals(d_tm.mkRoundingMode(RoundingMode.ROUND_TOWARD_NEGATIVE).getRoundingModeValue(), RoundingMode.ROUND_TOWARD_NEGATIVE); assertEquals(d_tm.mkRoundingMode(RoundingMode.ROUND_TOWARD_ZERO).getRoundingModeValue(), RoundingMode.ROUND_TOWARD_ZERO); assertEquals( d_tm.mkRoundingMode(RoundingMode.ROUND_NEAREST_TIES_TO_AWAY).getRoundingModeValue(), RoundingMode.ROUND_NEAREST_TIES_TO_AWAY); } @Test void getTuple() { Term t1 = d_tm.mkInteger(15); Term t2 = d_tm.mkReal(17, 25); Term t3 = d_tm.mkString("abc"); Term tup = d_tm.mkTuple(new Term[] {t1, t2, t3}); assertTrue(tup.isTupleValue()); assertEquals(Arrays.asList((new Term[] {t1, t2, t3})), Arrays.asList(tup.getTupleValue())); } @Test void getFloatingPoint() throws CVC5ApiException { Term bvval = d_tm.mkBitVector(16, "0000110000000011", 2); Term fp = d_tm.mkFloatingPoint(5, 11, bvval); assertTrue(fp.isFloatingPointValue()); assertFalse(fp.isFloatingPointPosZero()); assertFalse(fp.isFloatingPointNegZero()); assertFalse(fp.isFloatingPointPosInf()); assertFalse(fp.isFloatingPointNegInf()); assertFalse(fp.isFloatingPointNaN()); assertEquals(new Triplet(5L, 11L, bvval), fp.getFloatingPointValue()); assertTrue(d_tm.mkFloatingPointPosZero(5, 11).isFloatingPointPosZero()); assertTrue(d_tm.mkFloatingPointNegZero(5, 11).isFloatingPointNegZero()); assertTrue(d_tm.mkFloatingPointPosInf(5, 11).isFloatingPointPosInf()); assertTrue(d_tm.mkFloatingPointNegInf(5, 11).isFloatingPointNegInf()); assertTrue(d_tm.mkFloatingPointNaN(5, 11).isFloatingPointNaN()); } @Test void getSet() { Sort s = d_tm.mkSetSort(d_tm.getIntegerSort()); Term i1 = d_tm.mkInteger(5); Term i2 = d_tm.mkInteger(7); Term s1 = d_tm.mkEmptySet(s); Term s2 = d_tm.mkTerm(Kind.SET_SINGLETON, i1); Term s3 = d_tm.mkTerm(Kind.SET_SINGLETON, i1); Term s4 = d_tm.mkTerm(Kind.SET_SINGLETON, i2); Term s5 = d_tm.mkTerm(Kind.SET_UNION, s2, d_tm.mkTerm(Kind.SET_UNION, s3, s4)); assertTrue(s1.isSetValue()); assertTrue(s2.isSetValue()); assertTrue(s3.isSetValue()); assertTrue(s4.isSetValue()); assertFalse(s5.isSetValue()); s5 = d_solver.simplify(s5); assertTrue(s5.isSetValue()); assertSetsEquality(new Term[] {}, s1.getSetValue()); assertSetsEquality(new Term[] {i1}, s2.getSetValue()); assertSetsEquality(new Term[] {i1}, s3.getSetValue()); assertSetsEquality(new Term[] {i2}, s4.getSetValue()); assertSetsEquality(new Term[] {i1, i2}, s5.getSetValue()); } private void assertSetsEquality(Term[] A, Set B) { List a = Arrays.stream(A).sorted().collect(Collectors.toList()); List b = B.stream().sorted().collect(Collectors.toList()); assertEquals(a, b); } @Test void getSequence() { Sort s = d_tm.mkSequenceSort(d_tm.getIntegerSort()); Term i1 = d_tm.mkInteger(5); Term i2 = d_tm.mkInteger(7); Term s1 = d_tm.mkEmptySequence(s); Term s2 = d_tm.mkTerm(Kind.SEQ_UNIT, i1); Term s3 = d_tm.mkTerm(Kind.SEQ_UNIT, i1); Term s4 = d_tm.mkTerm(Kind.SEQ_UNIT, i2); Term s5 = d_tm.mkTerm(Kind.SEQ_CONCAT, s2, d_tm.mkTerm(Kind.SEQ_CONCAT, s3, s4)); assertTrue(s1.isSequenceValue()); assertTrue(!s2.isSequenceValue()); assertTrue(!s3.isSequenceValue()); assertTrue(!s4.isSequenceValue()); assertTrue(!s5.isSequenceValue()); s2 = d_solver.simplify(s2); s3 = d_solver.simplify(s3); s4 = d_solver.simplify(s4); s5 = d_solver.simplify(s5); assertEquals(Arrays.asList(new Term[] {}), Arrays.asList(s1.getSequenceValue())); assertEquals(Arrays.asList(new Term[] {i1}), Arrays.asList(s2.getSequenceValue())); assertEquals(Arrays.asList(new Term[] {i1}), Arrays.asList(s3.getSequenceValue())); assertEquals(Arrays.asList(new Term[] {i2}), Arrays.asList(s4.getSequenceValue())); assertEquals(Arrays.asList(new Term[] {i1, i1, i2}), Arrays.asList(s5.getSequenceValue())); } @Test void getCardinalityConstraint() throws CVC5ApiException { Sort su = d_tm.mkUninterpretedSort("u"); Term t = d_tm.mkCardinalityConstraint(su, 3); assertTrue(t.isCardinalityConstraint()); Pair cc = t.getCardinalityConstraint(); assertEquals(cc.first, su); assertEquals(cc.second, new BigInteger("3")); Term x = d_tm.mkConst(d_tm.getIntegerSort(), "x"); assertFalse(x.isCardinalityConstraint()); assertThrows(CVC5ApiException.class, () -> x.getCardinalityConstraint()); Term nullt = new Term(); assertThrows(CVC5ApiException.class, () -> nullt.isCardinalityConstraint()); } @Test void getRealAlgebraicNumber() throws CVC5ApiException { d_solver.setOption("produce-models", "true"); d_solver.setLogic("QF_NRA"); Sort realsort = d_tm.getRealSort(); Term x = d_tm.mkConst(realsort, "x"); Term x2 = d_tm.mkTerm(MULT, x, x); Term two = d_tm.mkReal(2, 1); Term eq = d_tm.mkTerm(EQUAL, x2, two); d_solver.assertFormula(eq); // Note that check-sat should only return "sat" if libpoly is enabled. // Otherwise, we do not test the following functionality. if (d_solver.checkSat().isSat()) { // We find a model for (x*x = 2), where x should be a real algebraic number. // We assert that its defining polynomial is non-null and its lower and // upper bounds are real. Term vx = d_solver.getValue(x); assertTrue(vx.isRealAlgebraicNumber()); Term y = d_tm.mkVar(realsort, "y"); Term poly = vx.getRealAlgebraicNumberDefiningPolynomial(y); assertTrue(!poly.isNull()); Term lb = vx.getRealAlgebraicNumberLowerBound(); assertTrue(lb.isRealValue()); Term ub = vx.getRealAlgebraicNumberUpperBound(); assertTrue(ub.isRealValue()); // cannot call with non-variable Term yc = d_tm.mkConst(realsort, "y"); assertThrows(CVC5ApiException.class, () ->vx.getRealAlgebraicNumberDefiningPolynomial(yc)); } } @Test void getSkolem() throws CVC5ApiException { // ordinary variables are not skolems Term x = d_solver.mkConst(d_solver.getIntegerSort(), "x"); assertFalse(x.isSkolem()); assertThrows(CVC5ApiException.class, () ->x.getSkolemId()); assertThrows(CVC5ApiException.class, () ->x.getSkolemIndices()); } @Test void testMkSkolem() throws CVC5ApiException { Sort integer = d_solver.getIntegerSort(); Sort arraySort = d_solver.mkArraySort(integer, integer); Term a = d_solver.mkConst(arraySort, "a"); Term b = d_solver.mkConst(arraySort, "b"); Term sk = d_tm.mkSkolem(SkolemId.ARRAY_DEQ_DIFF, new Term[] {a, b}); Term sk2 = d_tm.mkSkolem(SkolemId.ARRAY_DEQ_DIFF, new Term[] {b, a}); assertTrue(sk.isSkolem()); assertEquals(sk.getSkolemId(), SkolemId.ARRAY_DEQ_DIFF); assertEquals(Arrays.asList(new Term[] {a, b}), Arrays.asList(sk.getSkolemIndices())); // ARRAY_DEQ_DIFF is commutative, so the order of the indices is sorted. assertEquals(Arrays.asList(new Term[] {a, b}), Arrays.asList(sk2.getSkolemIndices())); } @Test void testGetNumIndices() throws CVC5ApiException { int numIndices = d_tm.getNumIndicesForSkolemId(SkolemId.ARRAY_DEQ_DIFF); assertEquals(numIndices, 2); } @Test void substitute() { Term x = d_tm.mkConst(d_tm.getIntegerSort(), "x"); Term one = d_tm.mkInteger(1); Term ttrue = d_tm.mkTrue(); Term xpx = d_tm.mkTerm(ADD, x, x); Term onepone = d_tm.mkTerm(ADD, one, one); assertEquals(xpx.substitute(x, one), onepone); assertEquals(onepone.substitute(one, x), xpx); // incorrect due to type assertThrows(CVC5ApiException.class, () -> xpx.substitute(one, ttrue)); // simultaneous substitution Term y = d_tm.mkConst(d_tm.getIntegerSort(), "y"); Term xpy = d_tm.mkTerm(ADD, x, y); Term xpone = d_tm.mkTerm(ADD, y, one); List es = new ArrayList<>(); List rs = new ArrayList<>(); es.add(x); rs.add(y); es.add(y); rs.add(one); assertEquals(xpy.substitute(es.toArray(new Term[0]), rs.toArray(new Term[0])), xpone); // incorrect substitution due to arity rs.remove(rs.size() - 1); assertThrows(CVC5ApiException.class, () -> xpy.substitute(es.toArray(new Term[0]), rs.toArray(new Term[0]))); // incorrect substitution due to types rs.add(ttrue); assertThrows(CVC5ApiException.class, () -> xpy.substitute(es.toArray(new Term[0]), rs.toArray(new Term[0]))); // null cannot substitute Term tnull = new Term(); assertThrows(CVC5ApiException.class, () -> tnull.substitute(one, x)); assertThrows(CVC5ApiException.class, () -> xpx.substitute(tnull, x)); assertThrows(CVC5ApiException.class, () -> xpx.substitute(x, tnull)); rs.remove(rs.size() - 1); rs.add(tnull); assertThrows(CVC5ApiException.class, () -> xpy.substitute(es.toArray(new Term[0]), rs.toArray(new Term[0]))); es.clear(); rs.clear(); es.add(x); rs.add(y); assertThrows(CVC5ApiException.class, () -> tnull.substitute(es.toArray(new Term[0]), rs.toArray(new Term[0]))); es.add(tnull); rs.add(one); assertThrows(CVC5ApiException.class, () -> xpx.substitute(es.toArray(new Term[0]), rs.toArray(new Term[0]))); } @Test void constArray() throws CVC5ApiException { Sort intsort = d_tm.getIntegerSort(); Sort arrsort = d_tm.mkArraySort(intsort, intsort); Term a = d_tm.mkConst(arrsort, "a"); Term one = d_tm.mkInteger(1); Term two = d_tm.mkBitVector(2, 2); Term iconst = d_tm.mkConst(intsort); Term constarr = d_tm.mkConstArray(arrsort, one); assertThrows(CVC5ApiException.class, () -> d_tm.mkConstArray(arrsort, two)); assertThrows(CVC5ApiException.class, () -> d_tm.mkConstArray(arrsort, iconst)); assertEquals(constarr.getKind(), CONST_ARRAY); assertEquals(constarr.getConstArrayBase(), one); assertThrows(CVC5ApiException.class, () -> a.getConstArrayBase()); Sort arrsort2 = d_tm.mkArraySort(d_tm.getRealSort(), d_tm.getRealSort()); Term zero_array = d_tm.mkConstArray(arrsort2, d_tm.mkReal(0)); Term stores = d_tm.mkTerm(STORE, zero_array, d_tm.mkReal(1), d_tm.mkReal(2)); stores = d_tm.mkTerm(STORE, stores, d_tm.mkReal(2), d_tm.mkReal(3)); stores = d_tm.mkTerm(STORE, stores, d_tm.mkReal(4), d_tm.mkReal(5)); } @Test void getSequenceValue() throws CVC5ApiException { Sort realsort = d_tm.getRealSort(); Sort seqsort = d_tm.mkSequenceSort(realsort); Term s = d_tm.mkEmptySequence(seqsort); assertEquals(s.getKind(), CONST_SEQUENCE); // empty sequence has zero elements Term[] cs = s.getSequenceValue(); assertTrue(cs.length == 0); // A seq.unit app is not a constant sequence (regardless of whether it is // applied to a constant). Term su = d_tm.mkTerm(SEQ_UNIT, d_tm.mkReal(1)); assertThrows(CVC5ApiException.class, () -> su.getSequenceValue()); } @Test void termScopedToString() { Sort intsort = d_tm.getIntegerSort(); Term x = d_tm.mkConst(intsort, "x"); assertEquals(x.toString(), "x"); Solver solver2; assertEquals(x.toString(), "x"); } }