Avoid using printSynthSolution in the python API and examples (#6564)
authoryoni206 <yoni206@users.noreply.github.com>
Thu, 20 May 2021 15:29:27 +0000 (08:29 -0700)
committerGitHub <noreply@github.com>
Thu, 20 May 2021 15:29:27 +0000 (15:29 +0000)
The function printSynthSolution declared here is going to be removed in #6521.

This PR removes it from the python API.
Following #6530, this PR also replaces its usages in the examples by a utility function.
For this, we also add support for getSynthSolutions in the python API.

examples/api/python/CMakeLists.txt
examples/api/python/__init__.py [new file with mode: 0644]
examples/api/python/sygus-fun.py
examples/api/python/sygus-grammar.py
examples/api/python/sygus-inv.py
examples/api/python/utils.py [new file with mode: 0644]
examples/api/utils.cpp
src/api/python/cvc5.pxd
src/api/python/cvc5.pxi

index 95e5fb80e1933d32f796ceb1b66b961d1dc3f138..ec4154f4f61c2366328993b582c2701f2f36ecdc 100644 (file)
@@ -53,5 +53,5 @@ foreach(example ${EXAMPLES_API_PYTHON})
   )
   set_tests_properties(${example_test} PROPERTIES
     LABELS "example"
-    ENVIRONMENT PYTHONPATH=${PYTHON_MODULE_PATH})
+    ENVIRONMENT PYTHONPATH=${PYTHON_MODULE_PATH}:${CMAKE_SOURCE_DIR}/api/python)
 endforeach()
diff --git a/examples/api/python/__init__.py b/examples/api/python/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
index 6e1440d66573274635ce395a5172b14109e0bd7c..d2ad1feb4f291f22f6221d32a2652253c8b42e54 100644 (file)
@@ -17,6 +17,7 @@
 
 import copy
 import pycvc5
+import utils
 from pycvc5 import kinds
 
 if __name__ == "__main__":
@@ -93,5 +94,5 @@ if __name__ == "__main__":
     # Output should be equivalent to:
     # (define-fun max ((x Int) (y Int)) Int (ite (<= x y) y x))
     # (define-fun min ((x Int) (y Int)) Int (ite (<= x y) x y))
-    slv.printSynthSolution()
-
+    terms = [max, min]
+    utils.print_synth_solutions(terms, slv.getSynthSolutions(terms))
index 406646f9f15e9f11deb17b1e56d5ba78814c3094..02a7dff48e5a5314581a79ec74834cbfbbda95a5 100644 (file)
@@ -17,6 +17,7 @@
 ##
 
 import copy
+import utils 
 import pycvc5
 from pycvc5 import kinds
 
@@ -87,4 +88,5 @@ if __name__ == "__main__":
     # (define-fun id2 ((x Int)) Int x)
     # (define-fun id3 ((x Int)) Int (+ x 0))
     # (define-fun id4 ((x Int)) Int (+ x (+ x (- x))))
-    slv.printSynthSolution()
+    terms = [id1, id2, id3, id4]
+    utils.print_synth_solutions(terms, slv.getSynthSolutions(terms))
index 0fa752b1e84c7d89972c7c5f5b4591307080d983..8273aa298f332003a19bf5fb2387bf3d635943de 100644 (file)
@@ -16,6 +16,7 @@
 # translation of sygus-inv.cpp .
 ##
 
+import utils
 import pycvc5
 from pycvc5 import kinds
 
@@ -60,7 +61,7 @@ if __name__ == "__main__":
   if slv.checkSynth().isUnsat():
     # Output should be equivalent to:
     # (define-fun inv-f ((x Int)) Bool (not (>= x 11)))
-    slv.printSynthSolution()
-
+    terms = [inv_f]
+    utils.print_synth_solutions(terms, slv.getSynthSolutions(terms))
 
 
diff --git a/examples/api/python/utils.py b/examples/api/python/utils.py
new file mode 100644 (file)
index 0000000..23b41d5
--- /dev/null
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 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.
+# #############################################################################
+#
+# Utility Methods, translated from examples/api/utils.h
+##
+
+import pycvc5
+from pycvc5 import kinds
+
+# Get the string version of define-fun command.
+# @param f the function to print
+# @param params the function parameters
+# @param body the function body
+# @return a string version of define-fun
+
+
+def define_fun_to_string(f, params, body):
+    sort = f.getSort()
+    if sort.isFunction():
+        sort = f.getSort().getFunctionCodomainSort()
+    result = ""
+    result += "(define-fun " + str(f) + " ("
+    for i in range(0, len(params)):
+        if i > 0:
+            result += " "
+        else:
+            result += "(" + str(params[i]) + " " + str(params[i].getSort()) + ")"
+    result += ") " + str(sort) + " " + str(body) + ")"
+    return result
+
+
+# Print solutions for synthesis conjecture to the standard output stream.
+# @param terms the terms for which the synthesis solutions were retrieved
+# @param sols the synthesis solutions of the given terms
+
+
+def print_synth_solutions(terms, sols):
+    result = ""
+    for i in range(0, len(terms)):
+        params = []
+        if sols[i].getKind() == kinds.Lambda:
+            params += sols[i][0]
+            body = sols[i][1]
+        result += "  " + define_fun_to_string(terms[i], params, body) + "\n"
+    print(result)
index b7385d688e1ab813c7a9d3a3c61a4380d7e15c1d..69676819ab508594a10af017d09517cb2386c31d 100644 (file)
  */
 std::string defineFunToString(const cvc5::api::Term& f,
                               const std::vector<cvc5::api::Term> params,
-                              const cvc5::api::Sort& sort,
                               const cvc5::api::Term body)
 {
+
+  cvc5::api::Sort sort = f.getSort();
+  if (sort.isFunction())
+  {
+    sort = sort.getFunctionCodomainSort();
+  }
   std::stringstream ss;
   ss << "(define-fun " << f << " (";
   for (size_t i = 0, n = params.size(); i < n; ++i)
@@ -57,12 +62,7 @@ void printSynthSolutions(const std::vector<cvc5::api::Term>& terms,
       params.insert(params.end(), sols[i][0].begin(), sols[i][0].end());
       body = sols[i][1];
     }
-    cvc5::api::Sort rangeSort = terms[i].getSort();
-    if (rangeSort.isFunction())
-    {
-      rangeSort = rangeSort.getFunctionCodomainSort();
-    }
-    std::cout << "  " << defineFunToString(terms[i], params, rangeSort, body)
+    std::cout << "  " << defineFunToString(terms[i], params, body)
               << std::endl;
   }
   std::cout << ')' << std::endl;
index 6fbc5ab57827961f6a67f248764965e2f9dc6a7f..205b82918367a3387a826aabd5963fcb9927b317 100644 (file)
@@ -180,7 +180,6 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api":
         vector[Term] getSynthSolutions(const vector[Term]& terms) except +
         Term synthInv(const string& symbol, const vector[Term]& bound_vars) except +
         Term synthInv(const string& symbol, const vector[Term]& bound_vars, Grammar grammar) except +
-        void printSynthSolution(ostream& out) except +
         # End of sygus related functions
 
         Term mkTrue() except +
index cd643d3f30dc256e4da2f7d8100daf04ebb38cb1..2fac78552166ee1a4766d059991c600f7a1a9f88 100644 (file)
@@ -958,6 +958,19 @@ cdef class Solver:
         t.cterm = self.csolver.getSynthSolution(term.cterm)
         return t
 
+    def getSynthSolutions(self, list terms):
+        result = []
+        cdef vector[c_Term] vec
+        for t in terms:
+            vec.push_back((<Term?> t).cterm)
+        cresult = self.csolver.getSynthSolutions(vec)
+        for s in cresult:
+            term = Term(self)
+            term.cterm = s
+            result.append(term)
+        return result
+
+
     def synthInv(self, symbol, bound_vars, Grammar grammar=None):
         cdef Term term = Term(self)
         cdef vector[c_Term] v
@@ -969,9 +982,6 @@ cdef class Solver:
             term.cterm = self.csolver.synthInv(symbol.encode(), <const vector[c_Term]&> v, grammar.cgrammar)
         return term
 
-    def printSynthSolution(self):
-        self.csolver.printSynthSolution(cout)
-
     @expand_list_arg(num_req_args=0)
     def checkSatAssuming(self, *assumptions):
         '''