2023-12-14 09:08:05 -06:00
|
|
|
###############################################################################
|
|
|
|
|
# Top contributors (to current version):
|
2025-01-23 09:54:20 -08:00
|
|
|
# Daniel Larraz, Andrew Reynolds, Aina Niemetz
|
2023-12-14 09:08:05 -06: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-12-14 09:08:05 -06: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.
|
|
|
|
|
# #############################################################################
|
|
|
|
|
##
|
|
|
|
|
|
|
|
|
|
from contextlib import contextmanager
|
|
|
|
|
import pytest
|
|
|
|
|
import cvc5
|
|
|
|
|
|
|
|
|
|
from cvc5 import InputParser, SymbolManager
|
|
|
|
|
|
|
|
|
|
@contextmanager
|
|
|
|
|
def does_not_raise():
|
|
|
|
|
yield
|
|
|
|
|
|
|
|
|
|
@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-12-14 09:08:05 -06:00
|
|
|
|
|
|
|
|
def test_get_solver(solver):
|
|
|
|
|
p = InputParser(solver)
|
|
|
|
|
assert p.getSolver() is solver
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
def test_symbol_manager(tm, solver):
|
2023-12-14 09:08:05 -06:00
|
|
|
p = InputParser(solver)
|
|
|
|
|
assert isinstance(p.getSymbolManager(), SymbolManager)
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
sm = SymbolManager(tm)
|
2023-12-14 09:08:05 -06:00
|
|
|
p2 = InputParser(solver, sm)
|
|
|
|
|
assert p2.getSymbolManager() is sm
|
|
|
|
|
|
|
|
|
|
def test_set_file_input(solver):
|
|
|
|
|
p = InputParser(solver)
|
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
|
p.setFileInput(cvc5.InputLanguage.SMT_LIB_2_6, "nonexistent.smt2")
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
def test_set_and_append_incremental_string_input(tm, solver):
|
|
|
|
|
sm = SymbolManager(tm)
|
2023-12-15 13:50:57 -06:00
|
|
|
p = InputParser(solver, sm)
|
|
|
|
|
p.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
p.appendIncrementalStringInput("(set-logic ALL)")
|
|
|
|
|
p.appendIncrementalStringInput("(declare-fun a () Bool)")
|
|
|
|
|
p.appendIncrementalStringInput("(declare-fun b () Int)")
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is not True
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is not True
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is not True
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
def test_set_and_append_incremental_string_input_interleave(tm, solver):
|
|
|
|
|
sm = SymbolManager(tm)
|
2023-12-14 09:08:05 -06:00
|
|
|
p = InputParser(solver, sm)
|
|
|
|
|
p.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
p.appendIncrementalStringInput("(set-logic ALL)")
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is not True
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
p.appendIncrementalStringInput("(declare-fun a () Bool)")
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is not True
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
p.appendIncrementalStringInput("(declare-fun b () Int)")
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is not True
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
def test_append_incremental_no_set(tm, solver):
|
|
|
|
|
sm = SymbolManager(tm)
|
2023-12-15 13:50:57 -06:00
|
|
|
p = InputParser(solver, sm)
|
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
|
p.appendIncrementalStringInput("(set-logic ALL)")
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
def test_set_string_input(tm, solver):
|
|
|
|
|
sm = SymbolManager(tm)
|
2023-12-15 13:50:57 -06:00
|
|
|
p = InputParser(solver, sm)
|
|
|
|
|
p.setStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "(set-logic ALL)", "test_input_parser")
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is False
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is True
|
|
|
|
|
|
|
|
|
|
def test_next_command_no_input(solver):
|
|
|
|
|
p = InputParser(solver)
|
|
|
|
|
p.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is True
|
|
|
|
|
t = p.nextTerm()
|
|
|
|
|
assert cmd.isNull() is True
|
2023-12-14 09:08:05 -06:00
|
|
|
|
|
|
|
|
def test_next_term(solver):
|
|
|
|
|
p = InputParser(solver)
|
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
|
p.nextTerm()
|
|
|
|
|
p.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
assert p.nextTerm().isNull() is True
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
def test_next_term2(tm, solver):
|
|
|
|
|
sm = SymbolManager(tm)
|
2023-12-14 09:08:05 -06:00
|
|
|
p = InputParser(solver, sm)
|
|
|
|
|
p.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
# parse a declaration command
|
|
|
|
|
p.appendIncrementalStringInput("(declare-fun a () Int)")
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() is not True
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
# now parse some terms
|
|
|
|
|
t = None
|
2023-12-15 13:50:57 -06:00
|
|
|
p.appendIncrementalStringInput("45\n")
|
2023-12-14 09:08:05 -06:00
|
|
|
with does_not_raise():
|
|
|
|
|
t = p.nextTerm()
|
|
|
|
|
assert t.isNull() is False
|
2023-12-15 13:50:57 -06:00
|
|
|
p.appendIncrementalStringInput("(+ a 1)\n")
|
2023-12-14 09:08:05 -06:00
|
|
|
with does_not_raise():
|
|
|
|
|
t = p.nextTerm()
|
|
|
|
|
assert t.isNull() is False
|
|
|
|
|
assert t.getKind() == cvc5.Kind.ADD
|
2023-12-15 13:50:57 -06:00
|
|
|
p.appendIncrementalStringInput("(+ b 1)\n")
|
2023-12-14 09:08:05 -06:00
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
|
t = p.nextTerm()
|
|
|
|
|
|
|
|
|
|
def parse_logic_command(p, logic):
|
|
|
|
|
p.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
p.appendIncrementalStringInput("(set-logic " + logic + ")\n")
|
|
|
|
|
return p.nextCommand()
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
def test_multiple_parsers(tm, solver):
|
|
|
|
|
sm = SymbolManager(tm)
|
2023-12-14 09:08:05 -06:00
|
|
|
p = InputParser(solver, sm)
|
|
|
|
|
# set a logic for the parser
|
|
|
|
|
cmd = parse_logic_command(p, "QF_LIA")
|
|
|
|
|
with does_not_raise():
|
|
|
|
|
cmd.invoke(solver, sm)
|
|
|
|
|
assert solver.isLogicSet() is True
|
|
|
|
|
assert solver.getLogic() == "QF_LIA"
|
|
|
|
|
assert sm.isLogicSet() is True
|
|
|
|
|
assert sm.getLogic() == "QF_LIA"
|
|
|
|
|
# cannot set logic on solver now
|
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
|
solver.setLogic("QF_LRA")
|
2024-06-18 16:21:47 -07:00
|
|
|
|
2023-12-14 09:08:05 -06:00
|
|
|
# possible to construct another parser with the same solver and symbol
|
|
|
|
|
# manager
|
|
|
|
|
p2 = InputParser(solver, p.getSymbolManager())
|
|
|
|
|
|
|
|
|
|
# possible to construct another parser with a fresh solver
|
2025-04-15 18:39:01 -07:00
|
|
|
s2 = cvc5.Solver(tm)
|
2023-12-14 09:08:05 -06:00
|
|
|
p3 = InputParser(s2, sm)
|
|
|
|
|
p3.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
|
|
|
|
|
# logic is automatically set on the solver
|
|
|
|
|
assert s2.isLogicSet() is True
|
|
|
|
|
assert s2.getLogic() == "QF_LIA"
|
|
|
|
|
# we cannot set the logic since it has already been set
|
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
|
parse_logic_command(p3, "QF_LRA")
|
2023-12-15 16:14:26 -06:00
|
|
|
assert p3.done() is True
|
2023-12-14 09:08:05 -06:00
|
|
|
|
|
|
|
|
# using a solver with the same logic is allowed
|
2025-04-15 18:39:01 -07:00
|
|
|
s3 = cvc5.Solver(tm)
|
2023-12-14 09:08:05 -06:00
|
|
|
s3.setLogic("QF_LIA")
|
|
|
|
|
p4 = InputParser(s3, sm)
|
|
|
|
|
p4.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
|
|
|
|
|
# using a solver with a different logic is not allowed
|
2025-04-15 18:39:01 -07:00
|
|
|
s4 = cvc5.Solver(tm)
|
2023-12-14 09:08:05 -06:00
|
|
|
s4.setLogic("QF_LRA")
|
|
|
|
|
p5 = InputParser(s4, sm)
|
|
|
|
|
with pytest.raises(RuntimeError):
|
|
|
|
|
p5.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
2024-03-19 13:39:35 -05:00
|
|
|
|
|
|
|
|
|
2024-06-18 16:21:47 -07:00
|
|
|
def test_get_declared_terms_and_sorts(tm, solver):
|
|
|
|
|
sm = SymbolManager(tm)
|
2024-03-19 13:39:35 -05:00
|
|
|
p = InputParser(solver, sm)
|
|
|
|
|
p.setIncrementalStringInput(cvc5.InputLanguage.SMT_LIB_2_6, "test_input_parser")
|
|
|
|
|
p.appendIncrementalStringInput("(set-logic ALL)")
|
|
|
|
|
p.appendIncrementalStringInput("(declare-sort U 0)")
|
|
|
|
|
p.appendIncrementalStringInput("(declare-fun x () U)")
|
|
|
|
|
for i in [0,1,2]:
|
|
|
|
|
cmd = p.nextCommand()
|
|
|
|
|
assert cmd.isNull() != True
|
|
|
|
|
cmd.invoke(solver, sm);
|
|
|
|
|
sorts = sm.getDeclaredSorts();
|
|
|
|
|
terms = sm.getDeclaredTerms();
|
|
|
|
|
assert len(sorts) == 1
|
|
|
|
|
assert len(terms) == 1
|
|
|
|
|
assert terms[0].getSort() == sorts[0]
|
2024-06-18 16:21:47 -07:00
|
|
|
|