/****************************************************************************** * Top contributors (to current version): * Abdalrhman Mohamed, Hans-Joerg Schurr, Aina Niemetz * * 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 guards of the C++ API functions. */ #include #include "test_api.h" namespace cvc5::internal { namespace test { class TestApiBlackProof : public TestApi { protected: Proof createProof() { d_solver->setOption("produce-proofs", "true"); Sort uSort = d_tm.mkUninterpretedSort("u"); Sort intSort = d_tm.getIntegerSort(); Sort boolSort = d_tm.getBooleanSort(); Sort uToIntSort = d_tm.mkFunctionSort({uSort}, intSort); Sort intPredSort = d_tm.mkFunctionSort({intSort}, boolSort); std::vector proof; Term x = d_tm.mkConst(uSort, "x"); Term y = d_tm.mkConst(uSort, "y"); Term f = d_tm.mkConst(uToIntSort, "f"); Term p = d_tm.mkConst(intPredSort, "p"); Term zero = d_tm.mkInteger(0); Term one = d_tm.mkInteger(1); Term f_x = d_tm.mkTerm(Kind::APPLY_UF, {f, x}); Term f_y = d_tm.mkTerm(Kind::APPLY_UF, {f, y}); Term sum = d_tm.mkTerm(Kind::ADD, {f_x, f_y}); Term p_0 = d_tm.mkTerm(Kind::APPLY_UF, {p, zero}); Term p_f_y = d_tm.mkTerm(Kind::APPLY_UF, {p, f_y}); d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {zero, f_x})); d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {zero, f_y})); d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {sum, one})); d_solver->assertFormula(p_0); d_solver->assertFormula(p_f_y.notTerm()); d_solver->checkSat(); return d_solver->getProof().front(); } Proof createRewriteProof() { d_solver->setOption("produce-proofs", "true"); d_solver->setOption("proof-granularity", "dsl-rewrite"); Sort intSort = d_tm.getIntegerSort(); Term x = d_tm.mkConst(intSort, "x"); Term zero = d_tm.mkInteger(0); Term geq = d_tm.mkTerm(Kind::GEQ, {x, zero}); Term leq = d_tm.mkTerm(Kind::LEQ, {zero, x}); d_solver->assertFormula(d_tm.mkTerm(Kind::DISTINCT, {geq, leq})); d_solver->checkSat(); return d_solver->getProof().front(); } }; TEST_F(TestApiBlackProof, nullProof) { Proof proof; ASSERT_EQ(proof.getRule(), ProofRule::UNKNOWN); ASSERT_EQ(std::hash()(ProofRule::UNKNOWN), static_cast(ProofRule::UNKNOWN)); ASSERT_TRUE(proof.getResult().isNull()); ASSERT_TRUE(proof.getChildren().empty()); ASSERT_TRUE(proof.getArguments().empty()); } TEST_F(TestApiBlackProof, getRule) { Proof proof = createProof(); ASSERT_EQ(proof.getRule(), ProofRule::SCOPE); } TEST_F(TestApiBlackProof, getRewriteRule) { Proof proof = createRewriteProof(); ASSERT_THROW(proof.getRewriteRule(), CVC5ApiException); ProofRule rule; std::vector stack; stack.push_back(proof); do { proof = stack.back(); stack.pop_back(); rule = proof.getRule(); std::vector children = proof.getChildren(); stack.insert(stack.cend(), children.cbegin(), children.cend()); } while (rule != ProofRule::DSL_REWRITE); ASSERT_NO_THROW(proof.getRewriteRule()); } TEST_F(TestApiBlackProof, getResult) { Proof proof = createProof(); ASSERT_NO_THROW(proof.getResult()); } TEST_F(TestApiBlackProof, getChildren) { Proof proof = createProof(); std::vector children; ASSERT_NO_THROW(children = proof.getChildren()); ASSERT_FALSE(children.empty()); } TEST_F(TestApiBlackProof, getArguments) { Proof proof = createProof(); ASSERT_NO_THROW(proof.getArguments()); } TEST_F(TestApiBlackProof, equalhash) { Proof x = createProof(); Proof y = x.getChildren()[0]; Proof z; ASSERT_TRUE(x == x); ASSERT_FALSE(x != x); ASSERT_FALSE(x == y); ASSERT_TRUE(x != y); ASSERT_FALSE(x == z); ASSERT_TRUE(x != z); ASSERT_TRUE(std::hash()(x) == std::hash()(x)); (void)std::hash{}(Proof()); ASSERT_FALSE(std::hash()(x) == std::hash()(y)); } } // namespace test } // namespace cvc5::internal