2023-10-12 12:05:01 -05:00
|
|
|
###############################################################################
|
|
|
|
|
# Top contributors (to current version):
|
2025-01-23 09:54:20 -08:00
|
|
|
# Abdalrhman Mohamed, Aina Niemetz, Hans-Joerg Schurr
|
2023-10-12 12:05:01 -05:00
|
|
|
#
|
|
|
|
|
# This file is part of the cvc5 project.
|
|
|
|
|
#
|
2025-01-23 09:54:20 -08:00
|
|
|
# Copyright (c) 2009-2025 by the authors listed in the file AUTHORS
|
2023-10-12 12:05:01 -05:00
|
|
|
# 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.
|
|
|
|
|
# #############################################################################
|
|
|
|
|
#
|
|
|
|
|
# Unit tests for proof API.
|
|
|
|
|
#
|
|
|
|
|
# Obtained by translating test/unit/api/sort_black.cpp
|
|
|
|
|
##
|
|
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
import cvc5
|
2024-04-18 08:09:59 -07:00
|
|
|
from cvc5 import Kind, ProofRule
|
2023-10-12 12:05:01 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
2024-03-14 14:34:58 -07:00
|
|
|
def tm():
|
|
|
|
|
return cvc5.TermManager()
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def solver(tm):
|
|
|
|
|
return cvc5.Solver(tm)
|
2023-10-12 12:05:01 -05:00
|
|
|
|
|
|
|
|
|
2024-03-14 14:34:58 -07:00
|
|
|
def create_proof(tm, solver):
|
2024-06-06 16:18:28 -07:00
|
|
|
solver.setOption("produce-proofs", "true")
|
2023-10-12 12:05:01 -05:00
|
|
|
|
2024-03-14 14:34:58 -07:00
|
|
|
uSort = tm.mkUninterpretedSort("u")
|
|
|
|
|
intSort = tm.getIntegerSort()
|
|
|
|
|
boolSort = tm.getBooleanSort()
|
|
|
|
|
uToIntSort = tm.mkFunctionSort(uSort, intSort)
|
|
|
|
|
intPredSort = tm.mkFunctionSort(intSort, boolSort)
|
2023-10-12 12:05:01 -05:00
|
|
|
|
2024-03-14 14:34:58 -07:00
|
|
|
x = tm.mkConst(uSort, "x")
|
|
|
|
|
y = tm.mkConst(uSort, "y")
|
|
|
|
|
f = tm.mkConst(uToIntSort, "f")
|
|
|
|
|
p = tm.mkConst(intPredSort, "p")
|
|
|
|
|
zero = tm.mkInteger(0)
|
|
|
|
|
one = tm.mkInteger(1)
|
|
|
|
|
f_x = tm.mkTerm(Kind.APPLY_UF, f, x)
|
|
|
|
|
f_y = tm.mkTerm(Kind.APPLY_UF, f, y)
|
|
|
|
|
summ = tm.mkTerm(Kind.ADD, f_x, f_y)
|
|
|
|
|
p_0 = tm.mkTerm(Kind.APPLY_UF, p, zero)
|
|
|
|
|
p_f_y = tm.mkTerm(Kind.APPLY_UF, p, f_y)
|
|
|
|
|
solver.assertFormula(tm.mkTerm(Kind.GT, zero, f_x))
|
|
|
|
|
solver.assertFormula(tm.mkTerm(Kind.GT, zero, f_y))
|
|
|
|
|
solver.assertFormula(tm.mkTerm(Kind.GT, summ, one))
|
2023-10-12 12:05:01 -05:00
|
|
|
solver.assertFormula(p_0)
|
|
|
|
|
solver.assertFormula(p_f_y.notTerm())
|
|
|
|
|
assert solver.checkSat().isUnsat()
|
|
|
|
|
|
|
|
|
|
return solver.getProof()[0]
|
|
|
|
|
|
|
|
|
|
|
2024-04-18 08:09:59 -07:00
|
|
|
def create_rewrite_proof(tm, solver):
|
|
|
|
|
solver.setOption("produce-proofs", "true")
|
|
|
|
|
solver.setOption("proof-granularity", "dsl-rewrite")
|
|
|
|
|
int_sort = tm.getIntegerSort()
|
|
|
|
|
x = tm.mkConst(int_sort, "x")
|
2025-02-10 16:35:29 -06:00
|
|
|
zero = tm.mkInteger(0)
|
|
|
|
|
geq = tm.mkTerm(Kind.GEQ, x, zero)
|
|
|
|
|
leq = tm.mkTerm(Kind.LEQ, zero, x)
|
|
|
|
|
solver.assertFormula(tm.mkTerm(Kind.DISTINCT, geq, leq))
|
2024-04-18 08:09:59 -07:00
|
|
|
solver.checkSat()
|
|
|
|
|
return solver.getProof()[0]
|
|
|
|
|
|
|
|
|
|
|
2024-06-06 16:18:28 -07:00
|
|
|
def test_null_proof(solver):
|
2025-10-02 09:41:03 -05:00
|
|
|
proof = cvc5.Proof()
|
2024-06-06 16:18:28 -07:00
|
|
|
assert proof.getRule() == ProofRule.UNKNOWN
|
|
|
|
|
assert hash(ProofRule.UNKNOWN) == hash(ProofRule.UNKNOWN)
|
|
|
|
|
assert proof.getResult().isNull()
|
|
|
|
|
assert len(proof.getChildren()) == 0
|
|
|
|
|
assert len(proof.getArguments()) == 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_rule(tm, solver):
|
2024-03-14 14:34:58 -07:00
|
|
|
proof = create_proof(tm, solver)
|
2023-10-12 12:05:01 -05:00
|
|
|
rule = proof.getRule()
|
2024-06-06 16:18:28 -07:00
|
|
|
assert rule == ProofRule.SCOPE
|
2023-10-12 12:05:01 -05:00
|
|
|
|
|
|
|
|
|
2024-04-18 08:09:59 -07:00
|
|
|
def test_get_rewrite_rule(tm, solver):
|
|
|
|
|
proof = create_rewrite_proof(tm, solver)
|
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
|
proof.getRewriteRule()
|
|
|
|
|
rule = None
|
|
|
|
|
stack = [proof]
|
|
|
|
|
while rule != ProofRule.DSL_REWRITE:
|
|
|
|
|
proof = stack.pop()
|
|
|
|
|
rule = proof.getRule()
|
|
|
|
|
children = proof.getChildren()
|
|
|
|
|
stack.extend(children)
|
|
|
|
|
assert proof.getRewriteRule() is not None
|
|
|
|
|
|
|
|
|
|
|
2024-03-14 14:34:58 -07:00
|
|
|
def test_get_result(tm, solver):
|
|
|
|
|
proof = create_proof(tm, solver)
|
2023-10-12 12:05:01 -05:00
|
|
|
proof.getResult()
|
|
|
|
|
|
|
|
|
|
|
2024-03-14 14:34:58 -07:00
|
|
|
def test_get_children(tm, solver):
|
|
|
|
|
proof = create_proof(tm, solver)
|
2023-10-12 12:05:01 -05:00
|
|
|
children = proof.getChildren()
|
|
|
|
|
assert len(children) > 0
|
|
|
|
|
|
|
|
|
|
|
2024-03-14 14:34:58 -07:00
|
|
|
def test_get_arguments(tm, solver):
|
|
|
|
|
proof = create_proof(tm, solver)
|
2023-10-12 12:05:01 -05:00
|
|
|
proof.getArguments()
|
2024-06-06 16:18:28 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_eq(tm, solver):
|
|
|
|
|
x = create_proof(tm, solver)
|
|
|
|
|
y = x.getChildren()[0]
|
2025-10-02 09:41:03 -05:00
|
|
|
z = cvc5.Proof()
|
2024-06-06 16:18:28 -07:00
|
|
|
|
|
|
|
|
assert x == x
|
|
|
|
|
assert not x != x
|
|
|
|
|
assert not x == y
|
|
|
|
|
assert x != y
|
|
|
|
|
assert not (x == z)
|
|
|
|
|
assert x != z
|
|
|
|
|
|
|
|
|
|
assert hash(x) == hash(x)
|