@PACKAGE_INIT@
set(CVC4_BINDINGS_JAVA @BUILD_SWIG_BINDINGS_JAVA@)
+set(CVC4_BINDINGS_PYTHON @BUILD_SWIG_BINDINGS_PYTHON@)
if(NOT TARGET CVC4::cvc4)
include(${CMAKE_CURRENT_LIST_DIR}/CVC4Targets.cmake)
add_subdirectory(api/java)
endif()
+
+if(CVC4_BINDINGS_PYTHON)
+ # If legacy Python API has been built
+ add_subdirectory(api/python)
+endif()
### A simple demonstration of the Python interface. Compare to the
### C++ interface in simple_vc_cxx.cpp; they are quite similar.
###
-### To run, use something like:
+### To run from a build directory, use something like:
###
-### ln -s ../builds/src/bindings/python/CVC4.py CVC4.py
-### ln -s ../builds/src/bindings/python/.libs/CVC4.so _CVC4.so
-### ./SimpleVC.py
+### PYTHONPATH=src/bindings/python python ../examples/SimpleVC.py
####
import CVC4
if __name__ == '__main__':
sys.exit(main())
-
#CVC4Streams
Combination
Datatypes
+ Exceptions
FloatingPointArith
HelloWorld
LinearArith
--- /dev/null
+/********************* */
+/*! \file Exceptions.java
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andres Noetzli
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2019 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.\endverbatim
+ **
+ ** \brief Catching CVC4 exceptions via the Java API.
+ **
+ ** A simple demonstration of catching CVC4 execptions via the Java API.
+ **/
+
+import edu.stanford.CVC4.*;
+
+public class Exceptions {
+ public static void main(String[] args) {
+ System.loadLibrary("cvc4jni");
+
+ ExprManager em = new ExprManager();
+ SmtEngine smt = new SmtEngine(em);
+
+ smt.setOption("produce-models", new SExpr(true));
+
+ // Setting an invalid option
+ try {
+ smt.setOption("non-existing", new SExpr(true));
+ System.exit(1);
+ } catch (edu.stanford.CVC4.Exception e) {
+ System.out.println(e.toString());
+ }
+
+ // Creating a term with an invalid type
+ try {
+ Type integer = em.integerType();
+ Expr x = em.mkVar("x", integer);
+ Expr invalidExpr = em.mkExpr(Kind.AND, x, x);
+ smt.checkSat(invalidExpr);
+ System.exit(1);
+ } catch (edu.stanford.CVC4.Exception e) {
+ System.out.println(e.toString());
+ }
+
+ // Asking for a model after unsat result
+ try {
+ smt.checkSat(em.mkConst(false));
+ smt.getModel();
+ System.exit(1);
+ } catch (edu.stanford.CVC4.Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+}
--- /dev/null
+set(EXAMPLES_API_PYTHON
+ exceptions
+)
+
+find_package(PythonInterp REQUIRED)
+
+# Find Python bindings in the corresponding python-*/site-packages directory.
+# Lookup Python module directory and store path in PYTHON_MODULE_PATH.
+execute_process(COMMAND
+ ${PYTHON_EXECUTABLE} -c
+ "from distutils.sysconfig import get_python_lib;\
+ print(get_python_lib(plat_specific=True,\
+ prefix='${CMAKE_PREFIX_PATH}/../..'))"
+ OUTPUT_VARIABLE PYTHON_MODULE_PATH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+foreach(example ${EXAMPLES_API_PYTHON})
+ set(example_test example/api/python/${example})
+ add_test(
+ NAME ${example_test}
+ COMMAND
+ "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/api/python/${example}.py"
+ )
+ set_tests_properties(${example_test} PROPERTIES
+ LABELS "example"
+ ENVIRONMENT PYTHONPATH=${PYTHON_MODULE_PATH})
+endforeach()
--- /dev/null
+#!/usr/bin/env python
+
+#####################
+## \file exceptions.py
+## \verbatim
+## Top contributors (to current version):
+## Andres Noetzli
+## This file is part of the CVC4 project.
+## Copyright (c) 2009-2020 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.\endverbatim
+##
+## \brief Catching CVC4 exceptions with the legacy Python API.
+##
+## A simple demonstration of catching CVC4 execptions with the legacy Python
+## API.
+
+import CVC4
+import sys
+
+
+def main():
+ em = CVC4.ExprManager()
+ smt = CVC4.SmtEngine(em)
+
+ smt.setOption("produce-models", CVC4.SExpr("true"))
+
+ # Setting an invalid option
+ try:
+ smt.setOption("non-existing", CVC4.SExpr("true"))
+ return 1
+ except CVC4.Exception as e:
+ print(e.toString())
+
+ # Creating a term with an invalid type
+ try:
+ integer = em.integerType()
+ x = em.mkVar("x", integer)
+ invalidExpr = em.mkExpr(CVC4.AND, x, x)
+ smt.checkSat(invalidExpr)
+ return 1
+ except CVC4.Exception as e:
+ print(e.toString())
+
+ # Asking for a model after unsat result
+ try:
+ smt.checkSat(em.mkBoolConst(False))
+ smt.getModel()
+ return 1
+ except CVC4.Exception as e:
+ print(e.toString())
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
%ignore CVC4::Exception::Exception(const char*);
%typemap(javabase) CVC4::Exception "java.lang.RuntimeException";
+// Make sure that the CVC4.Exception class of the Python API inherits from
+// BaseException and can be caught
+%exceptionclass CVC4::Exception;
+
%rename(CVC4IllegalArgumentException) CVC4::IllegalArgumentException;
%include "base/exception.h"
+// Declare that all functions in the interface can throw exceptions of type
+// CVC4::Exception and exceptions in general. SWIG catches those exceptions and
+// turns them into target language exceptions via "throws" typemaps.
+%catches(CVC4::Exception,...);
+
%import "bindings/swig.h"
%include "stdint.i"
#include "bindings/java_iterator_adapter.h"
#include "bindings/java_stream_adapters.h"
-%exception %{
- try {
- $action
- } catch(CVC4::Exception& e) {
- std::stringstream ss;
- ss << e.what() << ": " << e.getMessage();
- std::string explanation = ss.str();
- SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, explanation.c_str());
- }
-%}
-
-// Create a mapping from C++ Exceptions to Java Exceptions.
-// This is in a couple of throws typemaps, simply because it's sensitive to SWIG's concept of which namespace we're in.
-%typemap(throws) Exception %{
- std::string name = "edu/stanford/CVC4/$1_type";
- /*
- size_t i = name.find("::");
- if(i != std::string::npos) {
- size_t j = name.rfind("::");
- assert(i <= j);
- name.replace(i, j - i + 2, "/");
- }
- */
- jclass clazz = jenv->FindClass(name.c_str());
- assert(clazz != NULL && jenv->ExceptionOccurred() == NULL);
- jmethodID method = jenv->GetMethodID(clazz, "<init>", "(JZ)V");
- assert(method != NULL && jenv->ExceptionOccurred() == NULL);
- jthrowable t = static_cast<jthrowable>(jenv->NewObject(clazz, method, reinterpret_cast<uintptr_t>(new $1_type($1)), true));
- assert(t != NULL && jenv->ExceptionOccurred() == NULL);
- int status = jenv->Throw(t);
- assert(status == 0);
-%}
-%typemap(throws) CVC4::Exception %{
- std::string name = "edu/stanford/$1_type";
- size_t i = name.find("::");
- if(i != std::string::npos) {
- size_t j = name.rfind("::");
- assert(i <= j);
- name.replace(i, j - i + 2, "/");
- }
- jclass clazz = jenv->FindClass(name.c_str());
- assert(clazz != NULL && jenv->ExceptionOccurred() == NULL);
- jmethodID method = jenv->GetMethodID(clazz, "<init>", "(JZ)V");
- assert(method != NULL && jenv->ExceptionOccurred() == NULL);
- jthrowable t = static_cast<jthrowable>(jenv->NewObject(clazz, method, reinterpret_cast<uintptr_t>(new $1_type($1)), true));
- assert(t != NULL && jenv->ExceptionOccurred() == NULL);
- int status = jenv->Throw(t);
- assert(status == 0);
-%}
-
-%typemap(throws) CVC4::ModalException = CVC4::Exception;
-%typemap(throws) CVC4::LogicException = CVC4::Exception;
-%typemap(throws) CVC4::OptionException = CVC4::Exception;
-%typemap(throws) CVC4::IllegalArgumentException = CVC4::Exception;
-%typemap(throws) CVC4::AssertionException = CVC4::Exception;
-
-%typemap(throws) CVC4::TypeCheckingException = CVC4::Exception;
-%typemap(throws) CVC4::ScopeException = CVC4::Exception;
-%typemap(throws) CVC4::IllegalArgumentException = CVC4::Exception;
-%typemap(throws) IllegalArgumentException = Exception;
-%typemap(throws) CVC4::AssertionException = CVC4::Exception;
-
-// TIM: Really unclear why both of these are required
-%typemap(throws) CVC4::UnsafeInterruptException = CVC4::Exception;
-%typemap(throws) UnsafeInterruptException = CVC4::Exception;
-%typemap(throws) CVC4::parser::InputStreamException = CVC4::Exception;
-
-// Generate an error if the mapping from C++ CVC4 Exception to Java CVC4 Exception doesn't exist above
-%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY] %{
-#error "exception $1_type doesn't map to Java correctly---please edit src/cvc4.i and add it"
-%}
+// Map C++ exceptions of type CVC4::Exception to Java exceptions of type
+// edu.stanford.CVC4.Exception
+//
+// As suggested in:
+// http://www.swig.org/Doc3.0/SWIGDocumentation.html#Java_exception_typemap
+%typemap(throws, throws="edu.stanford.CVC4.Exception") CVC4::Exception {
+ jclass excep = jenv->FindClass("edu/stanford/CVC4/Exception");
+ if (excep)
+ jenv->ThrowNew(excep, $1.what());
+ return $null;
+}
%include "java/typemaps.i" // primitive pointers and references
%include "java/std_string.i" // map std::string to java.lang.String