A few more minor updates to match google repository with CVC4 repository
authorClark Barrett <clarkbarrett@google.com>
Thu, 23 Apr 2015 16:43:52 +0000 (09:43 -0700)
committerClark Barrett <clarkbarrett@google.com>
Thu, 23 Apr 2015 16:43:52 +0000 (09:43 -0700)
(mostly whitespace differences).

39 files changed:
config/ax_prog_doxygen.m4
examples/api/java/Strings.java
examples/api/strings.cpp
proofs/lfsc_checker/libwriter.cpp
proofs/lfsc_checker/libwriter.h
proofs/lfsc_checker/print_smt2.cpp
proofs/lfsc_checker/print_smt2.h
proofs/lfsc_checker/sccwriter.cpp
proofs/lfsc_checker/sccwriter.h
proofs/signatures/ex_bv.plf
proofs/signatures/th_bv.plf
src/theory/quantifiers/conjecture_generator.cpp
src/theory/quantifiers/conjecture_generator.h
src/theory/quantifiers/quant_conflict_find.cpp
src/theory/quantifiers/quant_conflict_find.h
test/regress/regress0/fmf/fc-pigeonhole19.smt2
test/regress/regress0/fmf/fc-unsat-pent.smt2
test/regress/regress0/fmf/fc-unsat-tot-2.smt2
test/regress/regress0/quantifiers/simp-typ-test.smt2
test/regress/regress0/strings/at001.smt2
test/regress/regress0/strings/bug001.smt2
test/regress/regress0/strings/bug002.smt2
test/regress/regress0/strings/escchar.smt2
test/regress/regress0/strings/escchar_25.smt2
test/regress/regress0/strings/fmf001.smt2
test/regress/regress0/strings/fmf002.smt2
test/regress/regress0/strings/leadingzero001.smt2
test/regress/regress0/strings/loop008.smt2
test/regress/regress0/strings/loop009.smt2
test/regress/regress0/strings/regexp001.smt2
test/regress/regress0/strings/regexp002.smt2
test/regress/regress0/strings/regexp003.smt2
test/regress/regress0/strings/reloop.smt2
test/regress/regress0/strings/str006.smt2
test/regress/regress0/strings/str007.smt2
test/regress/regress0/strings/substr001.smt2
test/regress/regress0/strings/type001.smt2
test/regress/regress0/strings/type002.smt2
test/regress/regress0/strings/type003.smt2

index 2d50f4e6da0d3b835407cd8e62b2e5c6b67b4f90..3a9744aa9dfb68fdf2b9ed154ef923364b9860d6 100644 (file)
-# This file is part of Autoconf.                       -*- Autoconf -*-\r
-\r
-# Renamed doxygen.m4 from acinclude.m4 for inclusion in CVC4\r
-\r
-# Copyright (C) 2004 Oren Ben-Kiki\r
-# This file is distributed under the same terms as the Autoconf macro files.\r
-\r
-########## CHANGELOG ##################\r
-# 2009-01-14 Martin Mann\r
-# * DX_ARG_ABLE : new variable 'DX_FLAG_DX_CURRENT_FEATURE'\r
-# * DX_CLEAR_DEPEND : use of explicit variable 'DX_FLAG_DX_CURRENT_FEATURE'\r
-#   in AC_SUBST instead of 'DX_FLAG[]DX_CURRENT_FEATURE' which is rejected by\r
-#   newer autotools  \r
-\r
-# Generate automatic documentation using Doxygen. Works in concert with the\r
-# aminclude.m4 file and a compatible doxygen configuration file. Defines the\r
-# following public macros:\r
-#\r
-# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.\r
-# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,\r
-# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'\r
-# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',\r
-# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment\r
-# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'\r
-# paper size.\r
-#\r
-# By default, HTML, PDF and PS documentation is generated as this seems to be\r
-# the most popular and portable combination. MAN pages created by Doxygen are\r
-# usually problematic, though by picking an appropriate subset and doing some\r
-# massaging they might be better than nothing. CHM and RTF are specific for MS\r
-# (note that you can't generate both HTML and CHM at the same time). The XML is\r
-# rather useless unless you apply specialized post-processing to it.\r
-#\r
-# The macro mainly controls the default state of the feature. The use can\r
-# override the default by specifying --enable or --disable. The macros ensure\r
-# that contradictory flags are not given (e.g., --enable-doxygen-html and\r
-# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)\r
-# Finally, each feature will be automatically disabled (with a warning) if the\r
-# required programs are missing.\r
-#\r
-# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with\r
-# the following parameters: a one-word name for the project for use as a\r
-# filename base etc., an optional configuration file name (the default is\r
-# 'Doxyfile', the same as Doxygen's default), and an optional output directory\r
-# name (the default is 'doxygen-doc').\r
-\r
-## ----------##\r
-## Defaults. ##\r
-## ----------##\r
-\r
-DX_ENV=""\r
-AC_DEFUN([DX_FEATURE_doc],  ON)\r
-AC_DEFUN([DX_FEATURE_dot],  ON)\r
-AC_DEFUN([DX_FEATURE_man],  OFF)\r
-AC_DEFUN([DX_FEATURE_html], ON)\r
-AC_DEFUN([DX_FEATURE_chm],  OFF)\r
-AC_DEFUN([DX_FEATURE_chi],  OFF)\r
-AC_DEFUN([DX_FEATURE_rtf],  OFF)\r
-AC_DEFUN([DX_FEATURE_xml],  OFF)\r
-AC_DEFUN([DX_FEATURE_pdf],  ON)\r
-AC_DEFUN([DX_FEATURE_ps],   ON)\r
-\r
-## --------------- ##\r
-## Private macros. ##\r
-## --------------- ##\r
-\r
-# DX_ENV_APPEND(VARIABLE, VALUE)\r
-# ------------------------------\r
-# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.\r
-AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])\r
-\r
-# DX_DIRNAME_EXPR\r
-# ---------------\r
-# Expand into a shell expression prints the directory part of a path.\r
-AC_DEFUN([DX_DIRNAME_EXPR],\r
-         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])\r
-\r
-# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)\r
-# -------------------------------------\r
-# Expands according to the M4 (static) status of the feature.\r
-AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])\r
-\r
-# DX_REQUIRE_PROG(VARIABLE, PROGRAM)\r
-# ----------------------------------\r
-# Require the specified program to be found for the DX_CURRENT_FEATURE to work.\r
-AC_DEFUN([DX_REQUIRE_PROG], [\r
-AC_PATH_TOOL([$1], [$2])\r
-if test "$DX_FLAG_DX_CURRENT_FEATURE$$1" = 1; then\r
-    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])\r
-    AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)\r
-fi\r
-])\r
-\r
-# DX_TEST_FEATURE(FEATURE)\r
-# ------------------------\r
-# Expand to a shell expression testing whether the feature is active.\r
-AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])\r
-\r
-# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)\r
-# -------------------------------------------------\r
-# Verify that a required features has the right state before trying to turn on\r
-# the DX_CURRENT_FEATURE.\r
-AC_DEFUN([DX_CHECK_DEPEND], [\r
-test "$DX_FLAG_$1" = "$2" \\r
-|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,\r
-                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])\r
-])\r
-\r
-# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)\r
-# ----------------------------------------------------------\r
-# Turn off the DX_CURRENT_FEATURE if the required feature is off.\r
-AC_DEFUN([DX_CLEAR_DEPEND], [\r
-test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)\r
-])\r
-\r
-\r
-# DX_FEATURE_ARG(FEATURE, DESCRIPTION,\r
-#                CHECK_DEPEND, CLEAR_DEPEND,\r
-#                REQUIRE, DO-IF-ON, DO-IF-OFF)\r
-# --------------------------------------------\r
-# Parse the command-line option controlling a feature. CHECK_DEPEND is called\r
-# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),\r
-# otherwise CLEAR_DEPEND is called to turn off the default state if a required\r
-# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional\r
-# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and\r
-# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.\r
-AC_DEFUN([DX_ARG_ABLE], [\r
-    AC_DEFUN([DX_CURRENT_FEATURE], [$1])\r
-    AC_DEFUN([DX_FLAG_DX_CURRENT_FEATURE], [DX_FLAG_$1])\r
-    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])\r
-    AC_ARG_ENABLE(doxygen-$1,\r
-                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],\r
-                                                      [--enable-doxygen-$1]),\r
-                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],\r
-                  [\r
-case "$enableval" in\r
-#(\r
-y|Y|yes|Yes|YES)\r
-    AC_SUBST([DX_FLAG_$1], 1)\r
-    $3\r
-;; #(\r
-n|N|no|No|NO)\r
-    AC_SUBST([DX_FLAG_$1], 0)\r
-;; #(\r
-*)\r
-    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])\r
-;;\r
-esac\r
-], [\r
-AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])\r
-$4\r
-])\r
-if DX_TEST_FEATURE([$1]); then\r
-    $5\r
-    :\r
-fi\r
-if DX_TEST_FEATURE([$1]); then\r
-    AM_CONDITIONAL(DX_COND_$1, :)\r
-    $6\r
-    :\r
-else\r
-    AM_CONDITIONAL(DX_COND_$1, false)\r
-    $7\r
-    :\r
-fi\r
-])\r
-\r
-## -------------- ##\r
-## Public macros. ##\r
-## -------------- ##\r
-\r
-# DX_XXX_FEATURE(DEFAULT_STATE)\r
-# -----------------------------\r
-AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])\r
-AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])\r
-AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])\r
-AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])\r
-AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])\r
-AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])\r
-AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])\r
-AC_DEFUN([DX_DOT_FEATURE],     [AC_DEFUN([DX_FEATURE_dot],  [$1])])\r
-AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])\r
-AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])\r
-\r
-# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])\r
-# ---------------------------------------------------------\r
-# PROJECT also serves as the base name for the documentation files.\r
-# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".\r
-AC_DEFUN([DX_INIT_DOXYGEN], [\r
-\r
-# Files:\r
-AC_SUBST([DX_PROJECT], [$1])\r
-AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])\r
-AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])\r
-\r
-# Environment variables used inside doxygen.cfg:\r
-DX_ENV_APPEND(SRCDIR, $srcdir)\r
-DX_ENV_APPEND(PROJECT, $DX_PROJECT)\r
-DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)\r
-DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)\r
-\r
-# Doxygen itself:\r
-DX_ARG_ABLE(doc, [generate any doxygen documentation],\r
-            [],\r
-            [],\r
-            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)\r
-             DX_REQUIRE_PROG([DX_PERL], perl)],\r
-            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])\r
-\r
-# Dot for graphics:\r
-DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],\r
-            [DX_CHECK_DEPEND(doc, 1)],\r
-            [DX_CLEAR_DEPEND(doc, 1)],\r
-            [DX_REQUIRE_PROG([DX_DOT], dot)],\r
-            [DX_ENV_APPEND(HAVE_DOT, YES)\r
-             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],\r
-            [DX_ENV_APPEND(HAVE_DOT, NO)])\r
-\r
-# Man pages generation:\r
-DX_ARG_ABLE(man, [generate doxygen manual pages],\r
-            [DX_CHECK_DEPEND(doc, 1)],\r
-            [DX_CLEAR_DEPEND(doc, 1)],\r
-            [],\r
-            [DX_ENV_APPEND(GENERATE_MAN, YES)],\r
-            [DX_ENV_APPEND(GENERATE_MAN, NO)])\r
-\r
-# RTF file generation:\r
-DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],\r
-            [DX_CHECK_DEPEND(doc, 1)],\r
-            [DX_CLEAR_DEPEND(doc, 1)],\r
-            [],\r
-            [DX_ENV_APPEND(GENERATE_RTF, YES)],\r
-            [DX_ENV_APPEND(GENERATE_RTF, NO)])\r
-\r
-# XML file generation:\r
-DX_ARG_ABLE(xml, [generate doxygen XML documentation],\r
-            [DX_CHECK_DEPEND(doc, 1)],\r
-            [DX_CLEAR_DEPEND(doc, 1)],\r
-            [],\r
-            [DX_ENV_APPEND(GENERATE_XML, YES)],\r
-            [DX_ENV_APPEND(GENERATE_XML, NO)])\r
-\r
-# (Compressed) HTML help generation:\r
-DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],\r
-            [DX_CHECK_DEPEND(doc, 1)],\r
-            [DX_CLEAR_DEPEND(doc, 1)],\r
-            [DX_REQUIRE_PROG([DX_HHC], hhc)],\r
-            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)\r
-             DX_ENV_APPEND(GENERATE_HTML, YES)\r
-             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],\r
-            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])\r
-\r
-# Seperate CHI file generation.\r
-DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],\r
-            [DX_CHECK_DEPEND(chm, 1)],\r
-            [DX_CLEAR_DEPEND(chm, 1)],\r
-            [],\r
-            [DX_ENV_APPEND(GENERATE_CHI, YES)],\r
-            [DX_ENV_APPEND(GENERATE_CHI, NO)])\r
-\r
-# Plain HTML pages generation:\r
-DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],\r
-            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],\r
-            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],\r
-            [],\r
-            [DX_ENV_APPEND(GENERATE_HTML, YES)],\r
-            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])\r
-\r
-# PostScript file generation:\r
-DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],\r
-            [DX_CHECK_DEPEND(doc, 1)],\r
-            [DX_CLEAR_DEPEND(doc, 1)],\r
-            [DX_REQUIRE_PROG([DX_LATEX], latex)\r
-             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)\r
-             DX_REQUIRE_PROG([DX_DVIPS], dvips)\r
-             DX_REQUIRE_PROG([DX_EGREP], egrep)])\r
-\r
-# PDF file generation:\r
-DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],\r
-            [DX_CHECK_DEPEND(doc, 1)],\r
-            [DX_CLEAR_DEPEND(doc, 1)],\r
-            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)\r
-             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)\r
-             DX_REQUIRE_PROG([DX_EGREP], egrep)])\r
-\r
-# LaTeX generation for PS and/or PDF:\r
-if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then\r
-    AM_CONDITIONAL(DX_COND_latex, :)\r
-    DX_ENV_APPEND(GENERATE_LATEX, YES)\r
-else\r
-    AM_CONDITIONAL(DX_COND_latex, false)\r
-    DX_ENV_APPEND(GENERATE_LATEX, NO)\r
-fi\r
-\r
-# Paper size for PS and/or PDF:\r
-AC_ARG_VAR(DOXYGEN_PAPER_SIZE,\r
-           [a4wide (default), a4, letter, legal or executive])\r
-case "$DOXYGEN_PAPER_SIZE" in\r
-#(\r
-"")\r
-    AC_SUBST(DOXYGEN_PAPER_SIZE, "")\r
-;; #(\r
-a4wide|a4|letter|legal|executive)\r
-    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)\r
-;; #(\r
-*)\r
-    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])\r
-;;\r
-esac\r
-\r
-#For debugging:\r
-#echo DX_FLAG_doc=$DX_FLAG_doc\r
-#echo DX_FLAG_dot=$DX_FLAG_dot\r
-#echo DX_FLAG_man=$DX_FLAG_man\r
-#echo DX_FLAG_html=$DX_FLAG_html\r
-#echo DX_FLAG_chm=$DX_FLAG_chm\r
-#echo DX_FLAG_chi=$DX_FLAG_chi\r
-#echo DX_FLAG_rtf=$DX_FLAG_rtf\r
-#echo DX_FLAG_xml=$DX_FLAG_xml\r
-#echo DX_FLAG_pdf=$DX_FLAG_pdf\r
-#echo DX_FLAG_ps=$DX_FLAG_ps\r
-#echo DX_ENV=$DX_ENV\r
-])\r
+# This file is part of Autoconf.                       -*- Autoconf -*-
+
+# Renamed doxygen.m4 from acinclude.m4 for inclusion in CVC4
+
+# Copyright (C) 2004 Oren Ben-Kiki
+# This file is distributed under the same terms as the Autoconf macro files.
+
+########## CHANGELOG ##################
+# 2009-01-14 Martin Mann
+# * DX_ARG_ABLE : new variable 'DX_FLAG_DX_CURRENT_FEATURE'
+# * DX_CLEAR_DEPEND : use of explicit variable 'DX_FLAG_DX_CURRENT_FEATURE'
+#   in AC_SUBST instead of 'DX_FLAG[]DX_CURRENT_FEATURE' which is rejected by
+#   newer autotools  
+
+# Generate automatic documentation using Doxygen. Works in concert with the
+# aminclude.m4 file and a compatible doxygen configuration file. Defines the
+# following public macros:
+#
+# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
+# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
+# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
+# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
+# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
+# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
+# paper size.
+#
+# By default, HTML, PDF and PS documentation is generated as this seems to be
+# the most popular and portable combination. MAN pages created by Doxygen are
+# usually problematic, though by picking an appropriate subset and doing some
+# massaging they might be better than nothing. CHM and RTF are specific for MS
+# (note that you can't generate both HTML and CHM at the same time). The XML is
+# rather useless unless you apply specialized post-processing to it.
+#
+# The macro mainly controls the default state of the feature. The use can
+# override the default by specifying --enable or --disable. The macros ensure
+# that contradictory flags are not given (e.g., --enable-doxygen-html and
+# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
+# Finally, each feature will be automatically disabled (with a warning) if the
+# required programs are missing.
+#
+# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
+# the following parameters: a one-word name for the project for use as a
+# filename base etc., an optional configuration file name (the default is
+# 'Doxyfile', the same as Doxygen's default), and an optional output directory
+# name (the default is 'doxygen-doc').
+
+## ----------##
+## Defaults. ##
+## ----------##
+
+DX_ENV=""
+AC_DEFUN([DX_FEATURE_doc],  ON)
+AC_DEFUN([DX_FEATURE_dot],  ON)
+AC_DEFUN([DX_FEATURE_man],  OFF)
+AC_DEFUN([DX_FEATURE_html], ON)
+AC_DEFUN([DX_FEATURE_chm],  OFF)
+AC_DEFUN([DX_FEATURE_chi],  OFF)
+AC_DEFUN([DX_FEATURE_rtf],  OFF)
+AC_DEFUN([DX_FEATURE_xml],  OFF)
+AC_DEFUN([DX_FEATURE_pdf],  ON)
+AC_DEFUN([DX_FEATURE_ps],   ON)
+
+## --------------- ##
+## Private macros. ##
+## --------------- ##
+
+# DX_ENV_APPEND(VARIABLE, VALUE)
+# ------------------------------
+# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
+AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
+
+# DX_DIRNAME_EXPR
+# ---------------
+# Expand into a shell expression prints the directory part of a path.
+AC_DEFUN([DX_DIRNAME_EXPR],
+         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
+
+# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
+# -------------------------------------
+# Expands according to the M4 (static) status of the feature.
+AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
+
+# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
+# ----------------------------------
+# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
+AC_DEFUN([DX_REQUIRE_PROG], [
+AC_PATH_TOOL([$1], [$2])
+if test "$DX_FLAG_DX_CURRENT_FEATURE$$1" = 1; then
+    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
+    AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)
+fi
+])
+
+# DX_TEST_FEATURE(FEATURE)
+# ------------------------
+# Expand to a shell expression testing whether the feature is active.
+AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
+
+# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
+# -------------------------------------------------
+# Verify that a required features has the right state before trying to turn on
+# the DX_CURRENT_FEATURE.
+AC_DEFUN([DX_CHECK_DEPEND], [
+test "$DX_FLAG_$1" = "$2" \
+|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
+                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])
+])
+
+# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
+# ----------------------------------------------------------
+# Turn off the DX_CURRENT_FEATURE if the required feature is off.
+AC_DEFUN([DX_CLEAR_DEPEND], [
+test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)
+])
+
+
+# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
+#                CHECK_DEPEND, CLEAR_DEPEND,
+#                REQUIRE, DO-IF-ON, DO-IF-OFF)
+# --------------------------------------------
+# Parse the command-line option controlling a feature. CHECK_DEPEND is called
+# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
+# otherwise CLEAR_DEPEND is called to turn off the default state if a required
+# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
+# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
+# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
+AC_DEFUN([DX_ARG_ABLE], [
+    AC_DEFUN([DX_CURRENT_FEATURE], [$1])
+    AC_DEFUN([DX_FLAG_DX_CURRENT_FEATURE], [DX_FLAG_$1])
+    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
+    AC_ARG_ENABLE(doxygen-$1,
+                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
+                                                      [--enable-doxygen-$1]),
+                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],
+                  [
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    AC_SUBST([DX_FLAG_$1], 1)
+    $3
+;; #(
+n|N|no|No|NO)
+    AC_SUBST([DX_FLAG_$1], 0)
+;; #(
+*)
+    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
+;;
+esac
+], [
+AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
+$4
+])
+if DX_TEST_FEATURE([$1]); then
+    $5
+    :
+fi
+if DX_TEST_FEATURE([$1]); then
+    AM_CONDITIONAL(DX_COND_$1, :)
+    $6
+    :
+else
+    AM_CONDITIONAL(DX_COND_$1, false)
+    $7
+    :
+fi
+])
+
+## -------------- ##
+## Public macros. ##
+## -------------- ##
+
+# DX_XXX_FEATURE(DEFAULT_STATE)
+# -----------------------------
+AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
+AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
+AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
+AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
+AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
+AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_DOT_FEATURE],     [AC_DEFUN([DX_FEATURE_dot],  [$1])])
+AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
+AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
+
+# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
+# ---------------------------------------------------------
+# PROJECT also serves as the base name for the documentation files.
+# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
+AC_DEFUN([DX_INIT_DOXYGEN], [
+
+# Files:
+AC_SUBST([DX_PROJECT], [$1])
+AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
+AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
+
+# Environment variables used inside doxygen.cfg:
+DX_ENV_APPEND(SRCDIR, $srcdir)
+DX_ENV_APPEND(PROJECT, $DX_PROJECT)
+DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
+DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
+
+# Doxygen itself:
+DX_ARG_ABLE(doc, [generate any doxygen documentation],
+            [],
+            [],
+            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
+             DX_REQUIRE_PROG([DX_PERL], perl)],
+            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
+
+# Dot for graphics:
+DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_DOT], dot)],
+            [DX_ENV_APPEND(HAVE_DOT, YES)
+             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
+            [DX_ENV_APPEND(HAVE_DOT, NO)])
+
+# Man pages generation:
+DX_ARG_ABLE(man, [generate doxygen manual pages],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_MAN, YES)],
+            [DX_ENV_APPEND(GENERATE_MAN, NO)])
+
+# RTF file generation:
+DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_RTF, YES)],
+            [DX_ENV_APPEND(GENERATE_RTF, NO)])
+
+# XML file generation:
+DX_ARG_ABLE(xml, [generate doxygen XML documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_XML, YES)],
+            [DX_ENV_APPEND(GENERATE_XML, NO)])
+
+# (Compressed) HTML help generation:
+DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_HHC], hhc)],
+            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
+             DX_ENV_APPEND(GENERATE_HTML, YES)
+             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
+            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
+
+# Seperate CHI file generation.
+DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
+            [DX_CHECK_DEPEND(chm, 1)],
+            [DX_CLEAR_DEPEND(chm, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_CHI, YES)],
+            [DX_ENV_APPEND(GENERATE_CHI, NO)])
+
+# Plain HTML pages generation:
+DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
+            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
+            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
+            [],
+            [DX_ENV_APPEND(GENERATE_HTML, YES)],
+            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
+
+# PostScript file generation:
+DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_LATEX], latex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_DVIPS], dvips)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# PDF file generation:
+DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# LaTeX generation for PS and/or PDF:
+if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
+    AM_CONDITIONAL(DX_COND_latex, :)
+    DX_ENV_APPEND(GENERATE_LATEX, YES)
+else
+    AM_CONDITIONAL(DX_COND_latex, false)
+    DX_ENV_APPEND(GENERATE_LATEX, NO)
+fi
+
+# Paper size for PS and/or PDF:
+AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
+           [a4wide (default), a4, letter, legal or executive])
+case "$DOXYGEN_PAPER_SIZE" in
+#(
+"")
+    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
+;; #(
+a4wide|a4|letter|legal|executive)
+    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
+;; #(
+*)
+    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
+;;
+esac
+
+#For debugging:
+#echo DX_FLAG_doc=$DX_FLAG_doc
+#echo DX_FLAG_dot=$DX_FLAG_dot
+#echo DX_FLAG_man=$DX_FLAG_man
+#echo DX_FLAG_html=$DX_FLAG_html
+#echo DX_FLAG_chm=$DX_FLAG_chm
+#echo DX_FLAG_chi=$DX_FLAG_chi
+#echo DX_FLAG_rtf=$DX_FLAG_rtf
+#echo DX_FLAG_xml=$DX_FLAG_xml
+#echo DX_FLAG_pdf=$DX_FLAG_pdf
+#echo DX_FLAG_ps=$DX_FLAG_ps
+#echo DX_ENV=$DX_ENV
+])
index 9437115a9c32fc5a64a4199e1d79098a91aa7ba1..bb9dcd8229f597171a27c13a9409c8adf8218746 100644 (file)
@@ -1,91 +1,91 @@
-/*********************                                                        */\r
-/*! \file Strings.java\r
- ** \verbatim\r
- ** Original author: Tianyi Liang\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Reasoning about strings with CVC4 via Java API.\r
- **\r
- ** A simple demonstration of reasoning about strings with CVC4 via Jave API.\r
- **/\r
-\r
-import edu.nyu.acsys.CVC4.*;\r
-\r
-public class Strings {\r
-  public static void main(String[] args) {\r
-    System.loadLibrary("cvc4jni");\r
-\r
-    ExprManager em = new ExprManager();\r
-    SmtEngine smt = new SmtEngine(em);\r
-\r
-    // Set the logic\r
-    smt.setLogic("S");\r
-\r
-    // Produce models\r
-    smt.setOption("produce-models", new SExpr(true));\r
-    // The option strings-exp is needed\r
-    smt.setOption("strings-exp", new SExpr(true));\r
-       // output-language\r
-    smt.setOption("output-language", new SExpr("smt2"));\r
-\r
-    // String type\r
-    Type string = em.stringType();\r
-\r
-    // String constants\r
-    Expr ab  = em.mkConst(new CVC4String("ab"));\r
-    Expr abc = em.mkConst(new CVC4String("abc"));\r
-    // Variables\r
-    Expr x = em.mkVar("x", string);\r
-    Expr y = em.mkVar("y", string);\r
-    Expr z = em.mkVar("z", string);\r
-\r
-    // String concatenation: x.ab.y\r
-    Expr lhs = em.mkExpr(Kind.STRING_CONCAT, x, ab, y);\r
-    // String concatenation: abc.z\r
-    Expr rhs = em.mkExpr(Kind.STRING_CONCAT, abc, z);;\r
-    // x.ab.y = abc.z\r
-    Expr formula1 = em.mkExpr(Kind.EQUAL, lhs, rhs);\r
-\r
-    // Length of y: |y|\r
-    Expr leny = em.mkExpr(Kind.STRING_LENGTH, y);\r
-    // |y| >= 0\r
-    Expr formula2 = em.mkExpr(Kind.GEQ, leny, em.mkConst(new Rational(0)));\r
-\r
-    // Regular expression: (ab[c-e]*f)|g|h\r
-    Expr r = em.mkExpr(Kind.REGEXP_UNION,\r
-      em.mkExpr(Kind.REGEXP_CONCAT,\r
-        em.mkExpr(Kind.STRING_TO_REGEXP, em.mkConst(new CVC4String("ab"))),\r
-        em.mkExpr(Kind.REGEXP_STAR,\r
-          em.mkExpr(Kind.REGEXP_RANGE, em.mkConst(new CVC4String("c")), em.mkConst(new CVC4String("e")))),\r
-        em.mkExpr(Kind.STRING_TO_REGEXP, em.mkConst(new CVC4String("f")))),\r
-      em.mkExpr(Kind.STRING_TO_REGEXP, em.mkConst(new CVC4String("g"))),\r
-      em.mkExpr(Kind.STRING_TO_REGEXP, em.mkConst(new CVC4String("h"))));\r
-\r
-    // String variables\r
-    Expr s1 = em.mkVar("s1", string);\r
-    Expr s2 = em.mkVar("s2", string);\r
-    // String concatenation: s1.s2\r
-    Expr s = em.mkExpr(Kind.STRING_CONCAT, s1, s2);\r
-\r
-    // s1.s2 in (ab[c-e]*f)|g|h\r
-    Expr formula3 = em.mkExpr(Kind.STRING_IN_REGEXP, s, r);\r
-\r
-       // Make a query\r
-    Expr q = em.mkExpr(Kind.AND,\r
-      formula1,\r
-      formula2,\r
-      formula3);\r
-\r
-     // check sat\r
-     Result result = smt.checkSat(q);\r
-     System.out.println("CVC4 reports: " + q + " is " + result + ".");\r
-\r
-     System.out.println("  x  = " + smt.getValue(x));\r
-     System.out.println("  s1.s2 = " + smt.getValue(s));\r
-  }\r
-}\r
+/*********************                                                        */
+/*! \file Strings.java
+ ** \verbatim
+ ** Original author: Tianyi Liang
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Reasoning about strings with CVC4 via Java API.
+ **
+ ** A simple demonstration of reasoning about strings with CVC4 via Jave API.
+ **/
+
+import edu.nyu.acsys.CVC4.*;
+
+public class Strings {
+  public static void main(String[] args) {
+    System.loadLibrary("cvc4jni");
+
+    ExprManager em = new ExprManager();
+    SmtEngine smt = new SmtEngine(em);
+
+    // Set the logic
+    smt.setLogic("S");
+
+    // Produce models
+    smt.setOption("produce-models", new SExpr(true));
+    // The option strings-exp is needed
+    smt.setOption("strings-exp", new SExpr(true));
+       // output-language
+    smt.setOption("output-language", new SExpr("smt2"));
+
+    // String type
+    Type string = em.stringType();
+
+    // String constants
+    Expr ab  = em.mkConst(new CVC4String("ab"));
+    Expr abc = em.mkConst(new CVC4String("abc"));
+    // Variables
+    Expr x = em.mkVar("x", string);
+    Expr y = em.mkVar("y", string);
+    Expr z = em.mkVar("z", string);
+
+    // String concatenation: x.ab.y
+    Expr lhs = em.mkExpr(Kind.STRING_CONCAT, x, ab, y);
+    // String concatenation: abc.z
+    Expr rhs = em.mkExpr(Kind.STRING_CONCAT, abc, z);;
+    // x.ab.y = abc.z
+    Expr formula1 = em.mkExpr(Kind.EQUAL, lhs, rhs);
+
+    // Length of y: |y|
+    Expr leny = em.mkExpr(Kind.STRING_LENGTH, y);
+    // |y| >= 0
+    Expr formula2 = em.mkExpr(Kind.GEQ, leny, em.mkConst(new Rational(0)));
+
+    // Regular expression: (ab[c-e]*f)|g|h
+    Expr r = em.mkExpr(Kind.REGEXP_UNION,
+      em.mkExpr(Kind.REGEXP_CONCAT,
+        em.mkExpr(Kind.STRING_TO_REGEXP, em.mkConst(new CVC4String("ab"))),
+        em.mkExpr(Kind.REGEXP_STAR,
+          em.mkExpr(Kind.REGEXP_RANGE, em.mkConst(new CVC4String("c")), em.mkConst(new CVC4String("e")))),
+        em.mkExpr(Kind.STRING_TO_REGEXP, em.mkConst(new CVC4String("f")))),
+      em.mkExpr(Kind.STRING_TO_REGEXP, em.mkConst(new CVC4String("g"))),
+      em.mkExpr(Kind.STRING_TO_REGEXP, em.mkConst(new CVC4String("h"))));
+
+    // String variables
+    Expr s1 = em.mkVar("s1", string);
+    Expr s2 = em.mkVar("s2", string);
+    // String concatenation: s1.s2
+    Expr s = em.mkExpr(Kind.STRING_CONCAT, s1, s2);
+
+    // s1.s2 in (ab[c-e]*f)|g|h
+    Expr formula3 = em.mkExpr(Kind.STRING_IN_REGEXP, s, r);
+
+       // Make a query
+    Expr q = em.mkExpr(Kind.AND,
+      formula1,
+      formula2,
+      formula3);
+
+     // check sat
+     Result result = smt.checkSat(q);
+     System.out.println("CVC4 reports: " + q + " is " + result + ".");
+
+     System.out.println("  x  = " + smt.getValue(x));
+     System.out.println("  s1.s2 = " + smt.getValue(s));
+  }
+}
index a424c654a546bd1accb233e13bffe1476cf80bc6..14ab0e64d944fb479e68d14cd08c598b8df5412b 100644 (file)
-/*********************                                                        */\r
-/*! \file sets.cpp\r
- ** \verbatim\r
- ** Original author: Tianyi Liang\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Reasoning about strings with CVC4 via C++ API.\r
- **\r
- ** A simple demonstration of reasoning about strings with CVC4 via C++ API.\r
- **/\r
-\r
-#include <iostream>\r
-\r
-//#include <cvc4/cvc4.h> // use this after CVC4 is properly installed\r
-#include "smt/smt_engine.h"\r
-\r
-using namespace CVC4;\r
-\r
-int main() {\r
-  ExprManager em;\r
-  SmtEngine smt(&em);\r
-\r
-  // Set the logic\r
-  smt.setLogic("S");\r
-\r
-  // Produce models\r
-  smt.setOption("produce-models", true);\r
-\r
-  // The option strings-exp is needed\r
-  smt.setOption("strings-exp", true);\r
-\r
-  // Set output language to SMTLIB2\r
-  std::cout << Expr::setlanguage(language::output::LANG_SMTLIB_V2);\r
-  \r
-  // String type\r
-  Type string = em.stringType();\r
-\r
-  // std::string\r
-  std::string std_str_ab("ab");\r
-  // CVC4::String\r
-  CVC4::String cvc4_str_ab(std_str_ab);\r
-  CVC4::String cvc4_str_abc("abc");\r
-  // String constants\r
-  Expr ab  = em.mkConst(cvc4_str_ab);\r
-  Expr abc = em.mkConst(CVC4::String("abc"));\r
-  // String variables\r
-  Expr x = em.mkVar("x", string);\r
-  Expr y = em.mkVar("y", string);\r
-  Expr z = em.mkVar("z", string);\r
-\r
-  // String concatenation: x.ab.y\r
-  Expr lhs = em.mkExpr(kind::STRING_CONCAT, x, ab, y);\r
-  // String concatenation: abc.z\r
-  Expr rhs = em.mkExpr(kind::STRING_CONCAT, abc, z);\r
-  // x.ab.y = abc.z\r
-  Expr formula1 = em.mkExpr(kind::EQUAL, lhs, rhs);\r
-\r
-  // Length of y: |y|\r
-  Expr leny = em.mkExpr(kind::STRING_LENGTH, y);\r
-  // |y| >= 0\r
-  Expr formula2 = em.mkExpr(kind::GEQ, leny, em.mkConst(Rational(0)));\r
-\r
-  // Regular expression: (ab[c-e]*f)|g|h\r
-  Expr r = em.mkExpr(kind::REGEXP_UNION,\r
-    em.mkExpr(kind::REGEXP_CONCAT,\r
-      em.mkExpr(kind::STRING_TO_REGEXP, em.mkConst(String("ab"))),\r
-      em.mkExpr(kind::REGEXP_STAR,\r
-        em.mkExpr(kind::REGEXP_RANGE, em.mkConst(String("c")), em.mkConst(String("e")))),\r
-      em.mkExpr(kind::STRING_TO_REGEXP, em.mkConst(String("f")))),\r
-    em.mkExpr(kind::STRING_TO_REGEXP, em.mkConst(String("g"))),\r
-    em.mkExpr(kind::STRING_TO_REGEXP, em.mkConst(String("h"))));\r
-\r
-  // String variables\r
-  Expr s1 = em.mkVar("s1", string);\r
-  Expr s2 = em.mkVar("s2", string);\r
-  // String concatenation: s1.s2\r
-  Expr s = em.mkExpr(kind::STRING_CONCAT, s1, s2);\r
-\r
-  // s1.s2 in (ab[c-e]*f)|g|h\r
-  Expr formula3 = em.mkExpr(kind::STRING_IN_REGEXP, s, r);\r
-\r
-  // Make a query\r
-  Expr q = em.mkExpr(kind::AND,\r
-    formula1,\r
-    formula2,\r
-    formula3);\r
-\r
-  // check sat\r
-  Result result = smt.checkSat(q);\r
-  std::cout << "CVC4 reports: " << q << " is " << result << "." << std::endl;\r
-\r
-  if(result == Result::SAT) {\r
-    std::cout << "  x  = " << smt.getValue(x) << std::endl;\r
-    std::cout << "  s1.s2 = " << smt.getValue(s) << std::endl;\r
-  }\r
-}\r
+/*********************                                                        */
+/*! \file sets.cpp
+ ** \verbatim
+ ** Original author: Tianyi Liang
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Reasoning about strings with CVC4 via C++ API.
+ **
+ ** A simple demonstration of reasoning about strings with CVC4 via C++ API.
+ **/
+
+#include <iostream>
+
+//#include <cvc4/cvc4.h> // use this after CVC4 is properly installed
+#include "smt/smt_engine.h"
+
+using namespace CVC4;
+
+int main() {
+  ExprManager em;
+  SmtEngine smt(&em);
+
+  // Set the logic
+  smt.setLogic("S");
+
+  // Produce models
+  smt.setOption("produce-models", true);
+
+  // The option strings-exp is needed
+  smt.setOption("strings-exp", true);
+
+  // Set output language to SMTLIB2
+  std::cout << Expr::setlanguage(language::output::LANG_SMTLIB_V2);
+  
+  // String type
+  Type string = em.stringType();
+
+  // std::string
+  std::string std_str_ab("ab");
+  // CVC4::String
+  CVC4::String cvc4_str_ab(std_str_ab);
+  CVC4::String cvc4_str_abc("abc");
+  // String constants
+  Expr ab  = em.mkConst(cvc4_str_ab);
+  Expr abc = em.mkConst(CVC4::String("abc"));
+  // String variables
+  Expr x = em.mkVar("x", string);
+  Expr y = em.mkVar("y", string);
+  Expr z = em.mkVar("z", string);
+
+  // String concatenation: x.ab.y
+  Expr lhs = em.mkExpr(kind::STRING_CONCAT, x, ab, y);
+  // String concatenation: abc.z
+  Expr rhs = em.mkExpr(kind::STRING_CONCAT, abc, z);
+  // x.ab.y = abc.z
+  Expr formula1 = em.mkExpr(kind::EQUAL, lhs, rhs);
+
+  // Length of y: |y|
+  Expr leny = em.mkExpr(kind::STRING_LENGTH, y);
+  // |y| >= 0
+  Expr formula2 = em.mkExpr(kind::GEQ, leny, em.mkConst(Rational(0)));
+
+  // Regular expression: (ab[c-e]*f)|g|h
+  Expr r = em.mkExpr(kind::REGEXP_UNION,
+    em.mkExpr(kind::REGEXP_CONCAT,
+      em.mkExpr(kind::STRING_TO_REGEXP, em.mkConst(String("ab"))),
+      em.mkExpr(kind::REGEXP_STAR,
+        em.mkExpr(kind::REGEXP_RANGE, em.mkConst(String("c")), em.mkConst(String("e")))),
+      em.mkExpr(kind::STRING_TO_REGEXP, em.mkConst(String("f")))),
+    em.mkExpr(kind::STRING_TO_REGEXP, em.mkConst(String("g"))),
+    em.mkExpr(kind::STRING_TO_REGEXP, em.mkConst(String("h"))));
+
+  // String variables
+  Expr s1 = em.mkVar("s1", string);
+  Expr s2 = em.mkVar("s2", string);
+  // String concatenation: s1.s2
+  Expr s = em.mkExpr(kind::STRING_CONCAT, s1, s2);
+
+  // s1.s2 in (ab[c-e]*f)|g|h
+  Expr formula3 = em.mkExpr(kind::STRING_IN_REGEXP, s, r);
+
+  // Make a query
+  Expr q = em.mkExpr(kind::AND,
+    formula1,
+    formula2,
+    formula3);
+
+  // check sat
+  Result result = smt.checkSat(q);
+  std::cout << "CVC4 reports: " << q << " is " << result << "." << std::endl;
+
+  if(result == Result::SAT) {
+    std::cout << "  x  = " << smt.getValue(x) << std::endl;
+    std::cout << "  s1.s2 = " << smt.getValue(s) << std::endl;
+  }
+}
index 49e9bbaad117dbc3a8add23318dd585f0599d068..016016c9d00f08cf149f58f6382374d0f2f40c49 100644 (file)
-#include "libwriter.h"\r
-#include <sstream>\r
-#include <algorithm>\r
-#include <fstream>\r
-\r
-void libwriter::get_var_name( const std::string& n, std::string& nn ) {\r
-  nn = std::string( n.c_str() );\r
-  for( int i = 0; i <(int)n.length(); i++ ){\r
-    char c = n[i];\r
-    if (c <= 47)\r
-        c += 65;\r
-    else if (c >= 58 && c <= 64)\r
-        c += 97-58;\r
-    if ((c >= 91 && c <= 94) || c == 96)\r
-        c += 104-91;\r
-    else if (c >= 123)\r
-        c -= 4;\r
-    nn[i] = c;\r
-  }  \r
-}\r
-\r
-void libwriter::write_file()\r
-{\r
-  //std::cout << "write lib" << std::endl;\r
-  std::ostringstream os_enum;\r
-  std::ostringstream os_print;\r
-  std::ostringstream os_constructor_h;\r
-  std::ostringstream os_constructor_c;\r
-\r
-  for ( int a=0; a<(int)syms.size(); a++ ) {\r
-    //std::cout << "sym #" << (a+1) << ": ";\r
-    //std::cout << ((SymSExpr*)syms[a])->s.c_str() << std::endl;\r
-    //defs[a]->print( std::cout );\r
-    //std::cout << std::endl;\r
-    \r
-    if( defs[a]->getclass()==CEXPR ){\r
-      //calculate which arguments are required for input\r
-      std::vector< Expr* > args;\r
-      std::vector< bool > argsNeed;\r
-      std::vector< Expr* > argTypes;\r
-      CExpr* c = ((CExpr*)defs[a]);\r
-      while( c->getop()==PI ){\r
-        //std::cout << c->kids[0] << std::endl;\r
-        if( ((CExpr*)c->kids[1])->getop()!=RUN ){\r
-          args.push_back( c->kids[0] );\r
-          argsNeed.push_back( true );\r
-          argTypes.push_back( c->kids[1] );\r
-        }\r
-        for( int b=0; b<(int)args.size(); b++ ){\r
-          if( argsNeed[b] ){\r
-            if( ((CExpr*)c->kids[1])->getop()==RUN ){\r
-              if( ((CExpr*)c->kids[1])->kids[1]->free_in( args[b] ) ){\r
-                argsNeed[b] = false;\r
-              }\r
-            }else{\r
-              if( c->kids[1]->free_in( args[b] ) ){\r
-                argsNeed[b] = false;\r
-              }\r
-            }\r
-          }\r
-        }\r
-        c = (CExpr*)(c->kids[2]);\r
-      }\r
-\r
-      //record if this declares a judgement\r
-      if( ((CExpr*)defs[a])->getop()==PI && c->getop()==TYPE ){\r
-        //std::cout << "This is a judgement" << std::endl;\r
-        judgements.push_back( syms[a] );\r
-      //record if this declares a proof rule\r
-      }else if( c->getclass()==CEXPR && std::find( judgements.begin(), judgements.end(), c->kids[0] )!=judgements.end() ){\r
-        std::cout << "Handle rule: " << ((SymSExpr*)syms[a])->s.c_str() << std::endl;\r
-        //std::cout << "These are required to input:" << std::endl;\r
-        //for( int b=0; b<(int)args.size(); b++ ){\r
-        //  if( argsNeed[b] ){\r
-        //    std::cout << ((SymSExpr*)args[b])->s.c_str() << std::endl;\r
-        //  }\r
-        //}\r
-        os_enum << "    rule_" << ((SymSExpr*)syms[a])->s.c_str() << "," << std::endl;\r
-\r
-        os_print << "  case rule_" << ((SymSExpr*)syms[a])->s.c_str() << ": os << \"";\r
-        os_print << ((SymSExpr*)syms[a])->s.c_str() << "\";break;" << std::endl;\r
-\r
-        std::ostringstream os_args;\r
-        os_args << "(";\r
-        bool firstTime = true;\r
-        for( int b=0; b<(int)args.size(); b++ ){\r
-          if( argsNeed[b] ){\r
-            if( !firstTime )\r
-              os_args << ",";\r
-            std::string str;\r
-            get_var_name( ((SymSExpr*)args[b])->s, str );\r
-            os_args << " LFSCProof* " << str.c_str();\r
-            firstTime = false;\r
-          }\r
-        }\r
-        if( !firstTime ){\r
-          os_args << " ";\r
-        }\r
-        os_args << ")";\r
-\r
-        os_constructor_h << "  static LFSCProof* make_" << ((SymSExpr*)syms[a])->s.c_str();\r
-        os_constructor_h << os_args.str().c_str() << ";" << std::endl;\r
-\r
-        os_constructor_c << "LFSCProof* LFSCProof::make_" << ((SymSExpr*)syms[a])->s.c_str();\r
-        os_constructor_c << os_args.str().c_str() << "{" << std::endl;\r
-        os_constructor_c << "  LFSCProof **kids = new LFSCProof *[" << (int)args.size()+1 << "];" << std::endl;\r
-        for( int b=0; b<(int)args.size(); b++ ){\r
-          os_constructor_c << "  kids[" << b << "] = ";\r
-          if( argsNeed[b] ){\r
-            std::string str;\r
-            get_var_name( ((SymSExpr*)args[b])->s, str );\r
-            os_constructor_c << str.c_str();\r
-          }else{\r
-            os_constructor_c << "hole";\r
-          }\r
-          os_constructor_c << ";" << std::endl;\r
-        }\r
-        os_constructor_c << "  kids[" << (int)args.size() << "] = 0;" << std::endl;\r
-        os_constructor_c << "  return new LFSCProofC( rule_" << ((SymSExpr*)syms[a])->s.c_str() << ", kids );" << std::endl;\r
-        os_constructor_c << "}" << std::endl << std::endl;\r
-      }\r
-    }\r
-\r
-    //write the header\r
-    static std::string filename( "lfsc_proof" );\r
-    std::fstream fsh;\r
-    std::string fnameh( filename );\r
-    fnameh.append(".h");\r
-    fsh.open( fnameh.c_str(), std::ios::out );\r
-\r
-    fsh << "#ifndef LFSC_PROOF_LIB_H" << std::endl;\r
-    fsh << "#define LFSC_PROOF_LIB_H" << std::endl;\r
-    fsh << std::endl;\r
-    fsh << "#include <string>" << std::endl;\r
-    fsh << std::endl;\r
-    fsh << "class LFSCProof{" << std::endl;\r
-    fsh << "protected:" << std::endl;\r
-    fsh << "  enum{" << std::endl;\r
-    fsh << os_enum.str().c_str();\r
-    fsh << "  };" << std::endl;\r
-    fsh << "  static LFSCProof* hole;" << std::endl;\r
-    fsh << "  LFSCProof(){}" << std::endl;\r
-    fsh << "public:" << std::endl;\r
-    fsh << "  virtual ~LFSCProof(){}" << std::endl;\r
-    fsh << "  static void init();" << std::endl;\r
-    fsh << std::endl;\r
-    fsh << "  //functions to build LFSC proofs" << std::endl;\r
-    fsh << os_constructor_h.str().c_str();\r
-    fsh << std::endl;\r
-    fsh << "  virtual void set_child( int i, LFSCProof* e ) {}" << std::endl;\r
-    fsh << "  virtual void print( std::ostream& os ){}" << std::endl;\r
-    fsh << "};" << std::endl;\r
-    fsh << std::endl;\r
-    fsh << "class LFSCProofC : public LFSCProof{" << std::endl;\r
-    fsh << "  short id;" << std::endl;\r
-    fsh << "  LFSCProof **kids;" << std::endl;\r
-    fsh << "public:" << std::endl;\r
-    fsh << "  LFSCProofC( short d_id, LFSCProof **d_kids ) : id( d_id ), kids( d_kids ){}" << std::endl;\r
-    fsh << "  void set_child( int i, LFSCProof* e ) { kids[i] = e; }" << std::endl;\r
-    fsh << "  void print( std::ostream& os );" << std::endl;\r
-    fsh << "};" << std::endl;\r
-    fsh << std::endl;\r
-    fsh << "class LFSCProofSym : public LFSCProof{" << std::endl;\r
-    fsh << "private:" << std::endl;\r
-    fsh << "  std::string s;" << std::endl;\r
-    fsh << "  LFSCProofSym( std::string ss ) : s( ss ){}" << std::endl;\r
-    fsh << "public:" << std::endl;\r
-    fsh << "  static LFSCProofSym* make( std::string ss ) { return new LFSCProofSym( ss ); }" << std::endl;\r
-    fsh << "  static LFSCProofSym* make( const char* ss ) { return new LFSCProofSym( std::string( ss ) ); }" << std::endl;\r
-    fsh << "  ~LFSCProofSym(){}" << std::endl;\r
-    fsh << "  void print( std::ostream& os ) { os << s.c_str(); }" << std::endl;\r
-    fsh << "};" << std::endl;\r
-    fsh << std::endl;\r
-    fsh << "class LFSCProofLam : public LFSCProof{" << std::endl;\r
-    fsh << "  LFSCProofSym* var;" << std::endl;\r
-    fsh << "  LFSCProof* body;" << std::endl;\r
-    fsh << "  LFSCProof* typ;" << std::endl;\r
-    fsh << "  LFSCProofLam( LFSCProofSym* d_var, LFSCProof* d_body, LFSCProof* d_typ ) : var( d_var ), body( d_body ), typ( d_typ ){}" << std::endl;\r
-    fsh << "public:" << std::endl;\r
-    fsh << "  static LFSCProof* make( LFSCProofSym* d_var, LFSCProof* d_body, LFSCProof* d_typ = NULL ) {" << std::endl;\r
-    fsh << "    return new LFSCProofLam( d_var, d_body, d_typ );" << std::endl;\r
-    fsh << "  }" << std::endl;\r
-    fsh << "  ~LFSCProofLam(){}" << std::endl;\r
-    fsh << std::endl;\r
-    fsh << "  void print( std::ostream& os );" << std::endl;\r
-    fsh << "};" << std::endl;\r
-    fsh << std::endl;\r
-    fsh << "#endif" << std::endl;\r
-\r
-    //write the cpp\r
-    std::fstream fsc;\r
-    std::string fnamec( filename );\r
-    fnamec.append(".cpp");\r
-    fsc.open( fnamec.c_str(), std::ios::out );\r
-\r
-    fsc << "#include \"lfsc_proof.h\"" << std::endl;\r
-    fsc << std::endl;\r
-    fsc << "LFSCProof* LFSCProof::hole = NULL;" << std::endl;\r
-    fsc << std::endl;\r
-    fsc << "void LFSCProof::init(){" << std::endl;\r
-    fsc << "  hole = LFSCProofSym::make( \"_\" );" << std::endl;\r
-    fsc << "}" << std::endl;\r
-    fsc << std::endl;\r
-    fsc << "void LFSCProofC::print( std::ostream& os ){" << std::endl;\r
-    fsc << "  os << \"(\";" << std::endl;\r
-    fsc << "  switch( id ){" << std::endl;\r
-    fsc << os_print.str().c_str();\r
-    fsc << "  }" << std::endl;\r
-    fsc << "  int counter = 0;" << std::endl;\r
-    fsc << "  while( kids[counter] ){" << std::endl;\r
-    fsc << "    os << \" \";" << std::endl;\r
-    fsc << "    kids[counter]->print( os );" << std::endl;\r
-    fsc << "    counter++;" << std::endl;\r
-    fsc << "  }" << std::endl;\r
-    fsc << "  os << \")\";" << std::endl;\r
-    fsc << "}" << std::endl;\r
-    fsc << std::endl;\r
-    fsc << "void LFSCProofLam::print( std::ostream& os ){" << std::endl;\r
-    fsc << "  os << \"(\";" << std::endl;\r
-    fsc << "  if( typ ){" << std::endl;\r
-    fsc << "    os << \"% \";" << std::endl;\r
-    fsc << "  }else{" << std::endl;\r
-    fsc << "    os << \"\\\\ \";" << std::endl;\r
-    fsc << "  }" << std::endl;\r
-    fsc << "  var->print( os );" << std::endl;\r
-    fsc << "  if( typ ){" << std::endl;\r
-    fsc << "    os << \" \";" << std::endl;\r
-    fsc << "    typ->print( os );" << std::endl;\r
-    fsc << "  }" << std::endl;\r
-    fsc << "  os << std::endl;" << std::endl;\r
-    fsc << "  body->print( os );" << std::endl;\r
-    fsc << "  os << \")\";" << std::endl;\r
-    fsc << "}" << std::endl;\r
-    fsc << std::endl;\r
-    fsc << os_constructor_c.str().c_str();\r
-    fsc << std::endl;\r
-  }\r
-}\r
+#include "libwriter.h"
+#include <sstream>
+#include <algorithm>
+#include <fstream>
+
+void libwriter::get_var_name( const std::string& n, std::string& nn ) {
+  nn = std::string( n.c_str() );
+  for( int i = 0; i <(int)n.length(); i++ ){
+    char c = n[i];
+    if (c <= 47)
+        c += 65;
+    else if (c >= 58 && c <= 64)
+        c += 97-58;
+    if ((c >= 91 && c <= 94) || c == 96)
+        c += 104-91;
+    else if (c >= 123)
+        c -= 4;
+    nn[i] = c;
+  }  
+}
+
+void libwriter::write_file()
+{
+  //std::cout << "write lib" << std::endl;
+  std::ostringstream os_enum;
+  std::ostringstream os_print;
+  std::ostringstream os_constructor_h;
+  std::ostringstream os_constructor_c;
+
+  for ( int a=0; a<(int)syms.size(); a++ ) {
+    //std::cout << "sym #" << (a+1) << ": ";
+    //std::cout << ((SymSExpr*)syms[a])->s.c_str() << std::endl;
+    //defs[a]->print( std::cout );
+    //std::cout << std::endl;
+    
+    if( defs[a]->getclass()==CEXPR ){
+      //calculate which arguments are required for input
+      std::vector< Expr* > args;
+      std::vector< bool > argsNeed;
+      std::vector< Expr* > argTypes;
+      CExpr* c = ((CExpr*)defs[a]);
+      while( c->getop()==PI ){
+        //std::cout << c->kids[0] << std::endl;
+        if( ((CExpr*)c->kids[1])->getop()!=RUN ){
+          args.push_back( c->kids[0] );
+          argsNeed.push_back( true );
+          argTypes.push_back( c->kids[1] );
+        }
+        for( int b=0; b<(int)args.size(); b++ ){
+          if( argsNeed[b] ){
+            if( ((CExpr*)c->kids[1])->getop()==RUN ){
+              if( ((CExpr*)c->kids[1])->kids[1]->free_in( args[b] ) ){
+                argsNeed[b] = false;
+              }
+            }else{
+              if( c->kids[1]->free_in( args[b] ) ){
+                argsNeed[b] = false;
+              }
+            }
+          }
+        }
+        c = (CExpr*)(c->kids[2]);
+      }
+
+      //record if this declares a judgement
+      if( ((CExpr*)defs[a])->getop()==PI && c->getop()==TYPE ){
+        //std::cout << "This is a judgement" << std::endl;
+        judgements.push_back( syms[a] );
+      //record if this declares a proof rule
+      }else if( c->getclass()==CEXPR && std::find( judgements.begin(), judgements.end(), c->kids[0] )!=judgements.end() ){
+        std::cout << "Handle rule: " << ((SymSExpr*)syms[a])->s.c_str() << std::endl;
+        //std::cout << "These are required to input:" << std::endl;
+        //for( int b=0; b<(int)args.size(); b++ ){
+        //  if( argsNeed[b] ){
+        //    std::cout << ((SymSExpr*)args[b])->s.c_str() << std::endl;
+        //  }
+        //}
+        os_enum << "    rule_" << ((SymSExpr*)syms[a])->s.c_str() << "," << std::endl;
+
+        os_print << "  case rule_" << ((SymSExpr*)syms[a])->s.c_str() << ": os << \"";
+        os_print << ((SymSExpr*)syms[a])->s.c_str() << "\";break;" << std::endl;
+
+        std::ostringstream os_args;
+        os_args << "(";
+        bool firstTime = true;
+        for( int b=0; b<(int)args.size(); b++ ){
+          if( argsNeed[b] ){
+            if( !firstTime )
+              os_args << ",";
+            std::string str;
+            get_var_name( ((SymSExpr*)args[b])->s, str );
+            os_args << " LFSCProof* " << str.c_str();
+            firstTime = false;
+          }
+        }
+        if( !firstTime ){
+          os_args << " ";
+        }
+        os_args << ")";
+
+        os_constructor_h << "  static LFSCProof* make_" << ((SymSExpr*)syms[a])->s.c_str();
+        os_constructor_h << os_args.str().c_str() << ";" << std::endl;
+
+        os_constructor_c << "LFSCProof* LFSCProof::make_" << ((SymSExpr*)syms[a])->s.c_str();
+        os_constructor_c << os_args.str().c_str() << "{" << std::endl;
+        os_constructor_c << "  LFSCProof **kids = new LFSCProof *[" << (int)args.size()+1 << "];" << std::endl;
+        for( int b=0; b<(int)args.size(); b++ ){
+          os_constructor_c << "  kids[" << b << "] = ";
+          if( argsNeed[b] ){
+            std::string str;
+            get_var_name( ((SymSExpr*)args[b])->s, str );
+            os_constructor_c << str.c_str();
+          }else{
+            os_constructor_c << "hole";
+          }
+          os_constructor_c << ";" << std::endl;
+        }
+        os_constructor_c << "  kids[" << (int)args.size() << "] = 0;" << std::endl;
+        os_constructor_c << "  return new LFSCProofC( rule_" << ((SymSExpr*)syms[a])->s.c_str() << ", kids );" << std::endl;
+        os_constructor_c << "}" << std::endl << std::endl;
+      }
+    }
+
+    //write the header
+    static std::string filename( "lfsc_proof" );
+    std::fstream fsh;
+    std::string fnameh( filename );
+    fnameh.append(".h");
+    fsh.open( fnameh.c_str(), std::ios::out );
+
+    fsh << "#ifndef LFSC_PROOF_LIB_H" << std::endl;
+    fsh << "#define LFSC_PROOF_LIB_H" << std::endl;
+    fsh << std::endl;
+    fsh << "#include <string>" << std::endl;
+    fsh << std::endl;
+    fsh << "class LFSCProof{" << std::endl;
+    fsh << "protected:" << std::endl;
+    fsh << "  enum{" << std::endl;
+    fsh << os_enum.str().c_str();
+    fsh << "  };" << std::endl;
+    fsh << "  static LFSCProof* hole;" << std::endl;
+    fsh << "  LFSCProof(){}" << std::endl;
+    fsh << "public:" << std::endl;
+    fsh << "  virtual ~LFSCProof(){}" << std::endl;
+    fsh << "  static void init();" << std::endl;
+    fsh << std::endl;
+    fsh << "  //functions to build LFSC proofs" << std::endl;
+    fsh << os_constructor_h.str().c_str();
+    fsh << std::endl;
+    fsh << "  virtual void set_child( int i, LFSCProof* e ) {}" << std::endl;
+    fsh << "  virtual void print( std::ostream& os ){}" << std::endl;
+    fsh << "};" << std::endl;
+    fsh << std::endl;
+    fsh << "class LFSCProofC : public LFSCProof{" << std::endl;
+    fsh << "  short id;" << std::endl;
+    fsh << "  LFSCProof **kids;" << std::endl;
+    fsh << "public:" << std::endl;
+    fsh << "  LFSCProofC( short d_id, LFSCProof **d_kids ) : id( d_id ), kids( d_kids ){}" << std::endl;
+    fsh << "  void set_child( int i, LFSCProof* e ) { kids[i] = e; }" << std::endl;
+    fsh << "  void print( std::ostream& os );" << std::endl;
+    fsh << "};" << std::endl;
+    fsh << std::endl;
+    fsh << "class LFSCProofSym : public LFSCProof{" << std::endl;
+    fsh << "private:" << std::endl;
+    fsh << "  std::string s;" << std::endl;
+    fsh << "  LFSCProofSym( std::string ss ) : s( ss ){}" << std::endl;
+    fsh << "public:" << std::endl;
+    fsh << "  static LFSCProofSym* make( std::string ss ) { return new LFSCProofSym( ss ); }" << std::endl;
+    fsh << "  static LFSCProofSym* make( const char* ss ) { return new LFSCProofSym( std::string( ss ) ); }" << std::endl;
+    fsh << "  ~LFSCProofSym(){}" << std::endl;
+    fsh << "  void print( std::ostream& os ) { os << s.c_str(); }" << std::endl;
+    fsh << "};" << std::endl;
+    fsh << std::endl;
+    fsh << "class LFSCProofLam : public LFSCProof{" << std::endl;
+    fsh << "  LFSCProofSym* var;" << std::endl;
+    fsh << "  LFSCProof* body;" << std::endl;
+    fsh << "  LFSCProof* typ;" << std::endl;
+    fsh << "  LFSCProofLam( LFSCProofSym* d_var, LFSCProof* d_body, LFSCProof* d_typ ) : var( d_var ), body( d_body ), typ( d_typ ){}" << std::endl;
+    fsh << "public:" << std::endl;
+    fsh << "  static LFSCProof* make( LFSCProofSym* d_var, LFSCProof* d_body, LFSCProof* d_typ = NULL ) {" << std::endl;
+    fsh << "    return new LFSCProofLam( d_var, d_body, d_typ );" << std::endl;
+    fsh << "  }" << std::endl;
+    fsh << "  ~LFSCProofLam(){}" << std::endl;
+    fsh << std::endl;
+    fsh << "  void print( std::ostream& os );" << std::endl;
+    fsh << "};" << std::endl;
+    fsh << std::endl;
+    fsh << "#endif" << std::endl;
+
+    //write the cpp
+    std::fstream fsc;
+    std::string fnamec( filename );
+    fnamec.append(".cpp");
+    fsc.open( fnamec.c_str(), std::ios::out );
+
+    fsc << "#include \"lfsc_proof.h\"" << std::endl;
+    fsc << std::endl;
+    fsc << "LFSCProof* LFSCProof::hole = NULL;" << std::endl;
+    fsc << std::endl;
+    fsc << "void LFSCProof::init(){" << std::endl;
+    fsc << "  hole = LFSCProofSym::make( \"_\" );" << std::endl;
+    fsc << "}" << std::endl;
+    fsc << std::endl;
+    fsc << "void LFSCProofC::print( std::ostream& os ){" << std::endl;
+    fsc << "  os << \"(\";" << std::endl;
+    fsc << "  switch( id ){" << std::endl;
+    fsc << os_print.str().c_str();
+    fsc << "  }" << std::endl;
+    fsc << "  int counter = 0;" << std::endl;
+    fsc << "  while( kids[counter] ){" << std::endl;
+    fsc << "    os << \" \";" << std::endl;
+    fsc << "    kids[counter]->print( os );" << std::endl;
+    fsc << "    counter++;" << std::endl;
+    fsc << "  }" << std::endl;
+    fsc << "  os << \")\";" << std::endl;
+    fsc << "}" << std::endl;
+    fsc << std::endl;
+    fsc << "void LFSCProofLam::print( std::ostream& os ){" << std::endl;
+    fsc << "  os << \"(\";" << std::endl;
+    fsc << "  if( typ ){" << std::endl;
+    fsc << "    os << \"% \";" << std::endl;
+    fsc << "  }else{" << std::endl;
+    fsc << "    os << \"\\\\ \";" << std::endl;
+    fsc << "  }" << std::endl;
+    fsc << "  var->print( os );" << std::endl;
+    fsc << "  if( typ ){" << std::endl;
+    fsc << "    os << \" \";" << std::endl;
+    fsc << "    typ->print( os );" << std::endl;
+    fsc << "  }" << std::endl;
+    fsc << "  os << std::endl;" << std::endl;
+    fsc << "  body->print( os );" << std::endl;
+    fsc << "  os << \")\";" << std::endl;
+    fsc << "}" << std::endl;
+    fsc << std::endl;
+    fsc << os_constructor_c.str().c_str();
+    fsc << std::endl;
+  }
+}
index 093cf541ba8cdfc873e9f48436eb6f8c40102590..91db5e9116802c493e16816a92a086ef8fbef5a5 100644 (file)
@@ -1,28 +1,28 @@
-#ifndef LIB_WRITER_H\r
-#define LIB_WRITER_H\r
-\r
-#include "expr.h"\r
-#include <map>\r
-\r
-class libwriter\r
-{\r
-private:\r
-  std::vector< Expr* > syms;\r
-  std::vector< Expr* > defs;\r
-\r
-  std::vector< Expr* > judgements;\r
-  //get the variable name\r
-  void get_var_name( const std::string& n, std::string& nn );\r
-public:\r
-  libwriter(){}\r
-  virtual ~libwriter(){}\r
-\r
-  void add_symbol( Expr* s, Expr* t ) { \r
-    syms.push_back( s );\r
-    defs.push_back( t ); \r
-  }\r
-\r
-  void write_file();\r
-};\r
-\r
-#endif\r
+#ifndef LIB_WRITER_H
+#define LIB_WRITER_H
+
+#include "expr.h"
+#include <map>
+
+class libwriter
+{
+private:
+  std::vector< Expr* > syms;
+  std::vector< Expr* > defs;
+
+  std::vector< Expr* > judgements;
+  //get the variable name
+  void get_var_name( const std::string& n, std::string& nn );
+public:
+  libwriter(){}
+  virtual ~libwriter(){}
+
+  void add_symbol( Expr* s, Expr* t ) { 
+    syms.push_back( s );
+    defs.push_back( t ); 
+  }
+
+  void write_file();
+};
+
+#endif
index 34cb00cc46ee16ba9b13dd96eb3fe1757749b464..40d9d12063e30c392c63b98ffbff09c63bc36d92 100644 (file)
-#include "print_smt2.h"\r
-\r
-#ifdef PRINT_SMT2\r
-\r
-void print_smt2( Expr* p, std::ostream& s, short mode )\r
-{\r
-  switch( p->getclass() )\r
-  {\r
-  case CEXPR:\r
-    {\r
-      switch( p->getop() )\r
-      {\r
-      case APP:\r
-        {\r
+#include "print_smt2.h"
+
+#ifdef PRINT_SMT2
+
+void print_smt2( Expr* p, std::ostream& s, short mode )
+{
+  switch( p->getclass() )
+  {
+  case CEXPR:
+    {
+      switch( p->getop() )
+      {
+      case APP:
+        {
           std::vector<Expr *> args;
-          Expr *head = p->collect_args(args, false);\r
-          short newMode = get_mode( head );\r
-          if( is_smt2_poly_formula( head ) )\r
-          {\r
-            s << "(";\r
-            head->print( s );\r
-            s << " ";\r
-            print_smt2( args[1], s, newMode );\r
-            s << " ";\r
-            print_smt2( args[2], s, newMode );\r
-            s << ")";\r
-          }\r
-          else if( ( mode==2 || mode==3 ) && mode==newMode )\r
-          {\r
-            print_smt2( args[0], s, newMode );\r
-            s << " ";\r
-            print_smt2( args[1], s, newMode );\r
-          }\r
-          else if( newMode==1 )\r
-          {\r
-            if( mode!=1 || newMode!=mode ){\r
-              s << "(";\r
-            }\r
-            print_smt2( args[2], s, newMode );\r
-            s << " ";\r
-            print_smt2( args[3], s, 0 );\r
-            if( mode!=1 || newMode!=mode ){\r
-              s << ")";\r
-            }\r
-          }\r
-          else\r
-          {\r
-            s << "(";\r
-            switch( newMode )\r
-            {\r
-            case 4: s << "=>";break;\r
-            default: head->print( s );break;\r
-            }\r
-            s << " ";\r
-            for( int a=0; a<(int)args.size(); a++ ){\r
-              print_smt2( args[a], s, newMode );\r
-              if( a!=(int)args.size()-1 )\r
-                s << " ";\r
-            }\r
-            s << ")";\r
-          }\r
-        }\r
-        break;\r
-      default:\r
-        std::cout << "Unhandled op " << p->getop() << std::endl;\r
-        break;\r
-      }\r
-    }\r
-    break;\r
-  case HOLE_EXPR:\r
-    {\r
-      HoleExpr *e = (HoleExpr *)p;\r
-      if( e->val ){\r
-        print_smt2( e->val, s, mode );\r
-      }else{\r
-        s << "_";\r
-      }\r
-    }\r
-    break;\r
-  case SYMS_EXPR:\r
-  case SYM_EXPR:\r
-    if( ((SymExpr*)p)->val )\r
-      print_smt2( ((SymExpr*)p)->val, s, mode );\r
-    else\r
-      p->print( s );\r
-    break;\r
-  default:\r
-    std::cout << "Unhandled class " << p->getclass() << std::endl;\r
-    break;\r
-  }\r
-}\r
-\r
-bool is_smt2_poly_formula( Expr* e )\r
-{\r
-  if( e->getclass()==SYMS_EXPR )\r
-  {\r
-    SymSExpr* s = (SymSExpr*)e;\r
-    static std::string eq("=");\r
-    static std::string distinct("distinct");\r
-    return s->s==eq || s->s==distinct;\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-short get_mode( Expr* e )\r
-{\r
-  if( e->getclass()==SYMS_EXPR ){\r
-    SymSExpr* s = (SymSExpr*)e;\r
-    static std::string applys("apply");\r
-    if ( s->s==applys ) return 1;\r
-    static std::string ands("and");\r
-    if ( s->s==ands ) return 2;\r
-    static std::string ors("or");\r
-    if ( s->s==ors ) return 3;\r
-    static std::string impls("impl");\r
-    if ( s->s==impls ) return 4;\r
-  }\r
-  return 0;\r
-}\r
-\r
-#endif\r
+          Expr *head = p->collect_args(args, false);
+          short newMode = get_mode( head );
+          if( is_smt2_poly_formula( head ) )
+          {
+            s << "(";
+            head->print( s );
+            s << " ";
+            print_smt2( args[1], s, newMode );
+            s << " ";
+            print_smt2( args[2], s, newMode );
+            s << ")";
+          }
+          else if( ( mode==2 || mode==3 ) && mode==newMode )
+          {
+            print_smt2( args[0], s, newMode );
+            s << " ";
+            print_smt2( args[1], s, newMode );
+          }
+          else if( newMode==1 )
+          {
+            if( mode!=1 || newMode!=mode ){
+              s << "(";
+            }
+            print_smt2( args[2], s, newMode );
+            s << " ";
+            print_smt2( args[3], s, 0 );
+            if( mode!=1 || newMode!=mode ){
+              s << ")";
+            }
+          }
+          else
+          {
+            s << "(";
+            switch( newMode )
+            {
+            case 4: s << "=>";break;
+            default: head->print( s );break;
+            }
+            s << " ";
+            for( int a=0; a<(int)args.size(); a++ ){
+              print_smt2( args[a], s, newMode );
+              if( a!=(int)args.size()-1 )
+                s << " ";
+            }
+            s << ")";
+          }
+        }
+        break;
+      default:
+        std::cout << "Unhandled op " << p->getop() << std::endl;
+        break;
+      }
+    }
+    break;
+  case HOLE_EXPR:
+    {
+      HoleExpr *e = (HoleExpr *)p;
+      if( e->val ){
+        print_smt2( e->val, s, mode );
+      }else{
+        s << "_";
+      }
+    }
+    break;
+  case SYMS_EXPR:
+  case SYM_EXPR:
+    if( ((SymExpr*)p)->val )
+      print_smt2( ((SymExpr*)p)->val, s, mode );
+    else
+      p->print( s );
+    break;
+  default:
+    std::cout << "Unhandled class " << p->getclass() << std::endl;
+    break;
+  }
+}
+
+bool is_smt2_poly_formula( Expr* e )
+{
+  if( e->getclass()==SYMS_EXPR )
+  {
+    SymSExpr* s = (SymSExpr*)e;
+    static std::string eq("=");
+    static std::string distinct("distinct");
+    return s->s==eq || s->s==distinct;
+  }else{
+    return false;
+  }
+}
+
+short get_mode( Expr* e )
+{
+  if( e->getclass()==SYMS_EXPR ){
+    SymSExpr* s = (SymSExpr*)e;
+    static std::string applys("apply");
+    if ( s->s==applys ) return 1;
+    static std::string ands("and");
+    if ( s->s==ands ) return 2;
+    static std::string ors("or");
+    if ( s->s==ors ) return 3;
+    static std::string impls("impl");
+    if ( s->s==impls ) return 4;
+  }
+  return 0;
+}
+
+#endif
index c70b1dfa4243c1c20070ea37d86e7eab6ab7104b..9bee0e81c782595b7106b46b23b1283d22b4ded0 100644 (file)
@@ -1,17 +1,17 @@
-#ifndef PRINT_SMT2_H\r
-#define PRINT_SMT2_H\r
-\r
-#define PRINT_SMT2\r
-\r
-#include "expr.h"\r
-\r
-#ifdef PRINT_SMT2\r
-void print_smt2( Expr* p, std::ostream& s, short mode = 0 );\r
-\r
-bool is_smt2_poly_formula( Expr* p );\r
-short get_mode( Expr* p );\r
-\r
-#endif\r
-\r
-\r
-#endif\r
+#ifndef PRINT_SMT2_H
+#define PRINT_SMT2_H
+
+#define PRINT_SMT2
+
+#include "expr.h"
+
+#ifdef PRINT_SMT2
+void print_smt2( Expr* p, std::ostream& s, short mode = 0 );
+
+bool is_smt2_poly_formula( Expr* p );
+short get_mode( Expr* p );
+
+#endif
+
+
+#endif
index d11a96b19818e80e70b00a13e0c366f9a8756caf..5c1da2a3f6e2b4aa05e69250fb2263519ba46bce 100644 (file)
-#include "sccwriter.h"\r
-\r
-#include <fstream>\r
-#include <sstream>\r
-\r
-int sccwriter::exprCount = 0;\r
-int sccwriter::strCount = 0;\r
-int sccwriter::argsCount = 0;\r
-int sccwriter::rnumCount = 0;\r
-\r
-int sccwriter::get_prog_index( const std::string& str )\r
-{\r
-  for( int a=0; a<(int)progNames.size(); a++ ){\r
-    if( progNames[a]==str ){\r
-      return a;\r
-    }\r
-  }\r
-  return -1;\r
-}\r
-\r
-int sccwriter::get_prog_index_by_expr( Expr* e )\r
-{\r
-  for( int a=0; a<(int)progPtrs.size(); a++ ){\r
-    if( progPtrs[a]==e ){\r
-      return a;\r
-    }\r
-  }\r
-  return -1;\r
-}\r
-\r
-bool sccwriter::is_var( const std::string& str )\r
-{\r
-  for( int a=0; a<(int)vars.size(); a++ ){\r
-    if( vars[a]==str ){\r
-      return true;\r
-    }\r
-  }\r
-  return false;\r
-}\r
-\r
-void sccwriter::add_global_sym( const std::string& str )\r
-{\r
-  for( int a=0; a<(int)globalSyms.size(); a++ ){\r
-    if( globalSyms[a]==str ){\r
-      return;\r
-    }\r
-  }\r
-  globalSyms.push_back( str );\r
-}\r
-\r
-void sccwriter::indent( std::ostream& os, int ind )\r
-{\r
-   for( int a=0; a<ind; a++ )\r
-   {\r
-      os << "   ";\r
-   }\r
-}\r
-\r
-void sccwriter::write_function_header( std::ostream& os, int index, int opts )\r
-{\r
-  //write the function header\r
-  std::string fname;\r
-  get_function_name( progNames[index], fname );\r
-  os << "Expr* " << fname.c_str() << "( ";\r
-  CExpr* progvars = (CExpr*)get_prog( index )->kids[1];\r
-  int counter = 0;\r
-  //write each argument\r
-  while( progvars->kids[counter] )\r
-  {\r
-    if( counter!=0 )\r
-    {\r
-      os << ", ";\r
-    }\r
-    os << "Expr* ";\r
-    write_variable( ((SymSExpr*)progvars->kids[counter])->s, os );\r
-    //add to vars if options are set to do so\r
-    if( opts&opt_write_add_args )\r
-    {\r
-      vars.push_back( ((SymSExpr*)progvars->kids[counter])->s );\r
-    }\r
-    counter++;\r
-  }\r
-  os << " )";\r
-  if( opts&opt_write_call_debug )\r
-  {\r
-     os << "{" << std::endl;\r
-     indent( os, 1 );\r
-     os << "std::cout << \"Call function " << fname.c_str() << " with arguments \";" << std::endl;\r
-     counter = 0; \r
-     while( progvars->kids[counter] )\r
-     {\r
-        if( counter!=0 )\r
-        {\r
-           indent( os, 1 );\r
-           os << "std::cout << \", \";" << std::endl;\r
-        }\r
-        indent( os, 1 );\r
-        write_variable( ((SymSExpr*)progvars->kids[counter])->s, os );\r
-        os << "->print( std::cout );" << std::endl;\r
-        counter++;\r
-     }\r
-     indent( os, 1 );\r
-     os << "std::cout << std::endl;" << std::endl;\r
-  }\r
-}\r
-\r
-void sccwriter::get_function_name( const std::string& pname, std::string& fname )\r
-{\r
-  fname = std::string( "f_" );\r
-  fname.append( pname );\r
-}\r
-\r
-void sccwriter::write_variable( const std::string& n, std::ostream& os )\r
-{\r
-  std::string nn;\r
-  get_var_name( n, nn );\r
-  os << nn.c_str();\r
-}\r
-\r
-void sccwriter::get_var_name( const std::string& n, std::string& nn ) {\r
-  nn = std::string( n.c_str() );\r
-  for( int i = 0; i <(int)n.length(); i++ ){\r
-    char c = n[i];\r
-    if (c <= 47)\r
-        c += 65;\r
-    else if (c >= 58 && c <= 64)\r
-        c += 97-58;\r
-    if ((c >= 91 && c <= 94) || c == 96)\r
-        c += 104-91;\r
-    else if (c >= 123)\r
-        c -= 4;\r
-    nn[i] = c;\r
-  }  \r
-}\r
-\r
-void sccwriter::write_file()\r
-{\r
-  static std::string filename( "scccode" );\r
-\r
-  //writer the h file\r
-  std::fstream fsh;\r
-  std::string fnameh( filename );\r
-  fnameh.append(".h");\r
-  fsh.open( fnameh.c_str(), std::ios::out );\r
-  //write the header in h\r
-  fsh << "#ifndef SCC_CODE_H" << std::endl;\r
-  fsh << "#define SCC_CODE_H" << std::endl << std::endl;\r
-  //include necessary files in h file\r
-  fsh << "#include \"check.h\"" << std::endl << std::endl;\r
-  //write the init function\r
-  fsh << "void init_compiled_scc();" << std::endl << std::endl;\r
-  //write the entry function\r
-  fsh << "Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args );" << std::endl << std::endl;\r
-  //write the side condition code functions\r
-  for( int n=0; n<(int)progs.size(); n++ )\r
-  {\r
-    //write the header in the h file\r
-    fsh << "inline ";\r
-    write_function_header( fsh, n );\r
-    fsh << ";" << std::endl << std::endl;\r
-  }\r
-  fsh << "#endif" << std::endl << std::endl;\r
-  fsh.close();\r
-\r
-\r
-  //writer the cpp code\r
-  std::fstream fsc;\r
-  std::string fnamec( filename );\r
-  fnamec.append(".cpp");\r
-  fsc.open( fnamec.c_str(), std::ios::out );\r
-  //include the h file in the cpp\r
-  fsc << "#include \"scccode.h\"" << std::endl << std::endl;\r
-  std::ostringstream fsc_funcs;\r
-  //write the side condition code functions\r
-  for( currProgram=0; currProgram<(int)progs.size(); currProgram++ )\r
-  {\r
-    //reset naming counters\r
-    vars.clear();\r
-    exprCount = 0;\r
-    strCount = 0;\r
-    argsCount = 0;\r
-    rnumCount = 0;\r
-\r
-    //for debugging\r
-    std::cout << "program #" << currProgram << " " << progNames[currProgram].c_str() << std::endl;\r
-\r
-    //write the function header\r
-    write_function_header( fsc_funcs, currProgram, opt_write_add_args|options );\r
-    if( (options&opt_write_call_debug)==0 )\r
-    {\r
-       fsc_funcs << "{" << std::endl;\r
-    }\r
-    //write the code\r
-    //std::vector< std::string > cleanVec;\r
-    //write_code( get_prog( n )->kids[2], fsc, 1, "return ", cleanVec );\r
-    //debug_write_code( progs[n].second->kids[2], fsc, 1 );\r
-    std::string expr;\r
-    write_expr( get_prog( currProgram )->kids[2], fsc_funcs, 1, expr );\r
-    indent( fsc_funcs, 1 );\r
-    fsc_funcs << "return " << expr.c_str() << ";" << std::endl;\r
-    fsc_funcs << "}" << std::endl << std::endl;\r
-  }\r
-  //write the predefined symbols necessary - symbols and progs\r
-  for( int a=0; a<(int)globalSyms.size(); a++ )\r
-  {\r
-    fsc << "Expr* e_" << globalSyms[a].c_str() << ";" << std::endl;\r
-  }\r
-  for( int a=0; a<(int)progs.size(); a++ )\r
-  {\r
-    fsc << "Expr* e_" << progNames[a].c_str() << ";" << std::endl;\r
-  }\r
-  fsc << std::endl;\r
-  //write the init function - initialize symbols and progs\r
-  fsc << "void init_compiled_scc(){" << std::endl;\r
-  for( int a=0; a<(int)globalSyms.size(); a++ )\r
-  {\r
-    indent( fsc, 1 );\r
-    fsc << "e_" << globalSyms[a].c_str() << " = symbols->get(\"" << globalSyms[a].c_str() << "\").first;" << std::endl;\r
-  }\r
-  for( int a=0; a<(int)progs.size(); a++ )\r
-  {\r
-    indent( fsc, 1 );\r
-    fsc << "e_" << progNames[a].c_str() << " = progs[\"" << progNames[a].c_str() << "\"];" << std::endl;\r
-  }\r
-  fsc << "}" << std::endl << std::endl;\r
-  fsc << "Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args ){" << std::endl;\r
-  //for( int n=0; n<(int)progs.size(); n++ ){\r
-  //  indent( fsc, 1 );\r
-  //  fsc << "static std::string s_" << progNames[n].c_str() << " = std::string( \"" << progNames[n].c_str() << "\" );" << std::endl;\r
-  //}\r
-  for( int n=0; n<(int)progs.size(); n++ ){\r
-    indent( fsc, 1 );\r
-    if( n!=0 ){\r
-      fsc << "}else ";\r
-    }\r
-    //for each function, test to see if the string matches the name of the function\r
-    fsc << "if( p==e_" << progNames[n].c_str() << " ){" << std::endl;\r
-    indent( fsc, 2 );\r
-    std::string fname;\r
-    get_function_name( progNames[n], fname );\r
-    //map the function to the proper function\r
-    fsc << "return " << fname.c_str() << "( ";\r
-    //write the arguments to the function from args\r
-    CExpr* progvars = (CExpr*)get_prog( n )->kids[1];\r
-    int counter = 0;\r
-    bool firstTime = true;\r
-    while( progvars->kids[counter] )\r
-    {\r
-      if( !firstTime )\r
-      {\r
-        fsc << ", ";\r
-      }\r
-      fsc << "args[" << counter << "]";\r
-      firstTime = false;\r
-      counter++;\r
-    }\r
-    fsc << " );" << std::endl;\r
-  }\r
-  indent( fsc, 1 );\r
-  fsc << "}else{" << std::endl;\r
-  indent( fsc, 2 );\r
-  //return null in the case the function could not be found\r
-  fsc << "return NULL;" << std::endl;\r
-  indent( fsc, 1 );\r
-  fsc << "}" << std::endl;\r
-  fsc << "}" << std::endl << std::endl;\r
-  fsc << fsc_funcs.str().c_str();\r
-\r
-  fsc.close();\r
-}\r
-\r
-void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* retModStr, int opts )\r
-{\r
-  std::string retModString;\r
-  std::string incString;\r
-  if ( retModStr )\r
-  {\r
-    retModString = std::string( retModStr );\r
-    retModString.append( " = " );\r
-    incString = std::string( retModStr );\r
-    incString.append( "->inc();" );\r
-  }\r
-  switch( code->getclass() )\r
-  {\r
-  case INT_EXPR:\r
-    {\r
-      indent( os, ind );\r
-      os << retModString.c_str();\r
-      os << "new IntExpr( " << mpz_get_si( ((IntExpr*)code)->n ) << " );" << std::endl;\r
-      indent( os, ind );\r
-      os << incString.c_str() << std::endl;\r
-    }\r
-    break;\r
-  case RAT_EXPR:\r
-    {\r
-      mpz_t num, den;\r
-      mpz_init(num);\r
-      mpz_init(den);\r
-      mpq_get_num( num, ((RatExpr*)code)->n );\r
-      mpq_get_den( den, ((RatExpr*)code)->n );\r
-      indent( os, ind );\r
-      os << retModString.c_str();\r
-      os << "new RatExpr( " << mpz_get_si( num ) << ", " << mpz_get_si( den ) << " );" << std::endl;\r
-      indent( os, ind );\r
-      os << incString.c_str() << std::endl;\r
-    }\r
-    break;\r
-  case SYMS_EXPR:\r
-    {\r
-      //if it is a variable, simply write it to buffer\r
-      if( is_var( ((SymSExpr*)code)->s ) )\r
-      {\r
-        indent( os, ind );\r
-        os << retModString.c_str();\r
-        write_variable( ((SymSExpr*)code)->s.c_str(), os );\r
-        os << ";" << std::endl;  \r
-      }\r
-      else  //else must look at symbol lookup table\r
-      {\r
-        std::string var;\r
-        get_var_name( ((SymSExpr*)code)->s, var );\r
-        indent( os, ind );\r
-        os << retModString.c_str() << "e_" << var.c_str() << ";" << std::endl;\r
-        add_global_sym( var ); \r
-      }\r
-      indent( os, ind );\r
-      os << incString.c_str() << std::endl;\r
-    }\r
-    break;\r
-  default:\r
-    switch( code->getop() )\r
-    {\r
+#include "sccwriter.h"
+
+#include <fstream>
+#include <sstream>
+
+int sccwriter::exprCount = 0;
+int sccwriter::strCount = 0;
+int sccwriter::argsCount = 0;
+int sccwriter::rnumCount = 0;
+
+int sccwriter::get_prog_index( const std::string& str )
+{
+  for( int a=0; a<(int)progNames.size(); a++ ){
+    if( progNames[a]==str ){
+      return a;
+    }
+  }
+  return -1;
+}
+
+int sccwriter::get_prog_index_by_expr( Expr* e )
+{
+  for( int a=0; a<(int)progPtrs.size(); a++ ){
+    if( progPtrs[a]==e ){
+      return a;
+    }
+  }
+  return -1;
+}
+
+bool sccwriter::is_var( const std::string& str )
+{
+  for( int a=0; a<(int)vars.size(); a++ ){
+    if( vars[a]==str ){
+      return true;
+    }
+  }
+  return false;
+}
+
+void sccwriter::add_global_sym( const std::string& str )
+{
+  for( int a=0; a<(int)globalSyms.size(); a++ ){
+    if( globalSyms[a]==str ){
+      return;
+    }
+  }
+  globalSyms.push_back( str );
+}
+
+void sccwriter::indent( std::ostream& os, int ind )
+{
+   for( int a=0; a<ind; a++ )
+   {
+      os << "   ";
+   }
+}
+
+void sccwriter::write_function_header( std::ostream& os, int index, int opts )
+{
+  //write the function header
+  std::string fname;
+  get_function_name( progNames[index], fname );
+  os << "Expr* " << fname.c_str() << "( ";
+  CExpr* progvars = (CExpr*)get_prog( index )->kids[1];
+  int counter = 0;
+  //write each argument
+  while( progvars->kids[counter] )
+  {
+    if( counter!=0 )
+    {
+      os << ", ";
+    }
+    os << "Expr* ";
+    write_variable( ((SymSExpr*)progvars->kids[counter])->s, os );
+    //add to vars if options are set to do so
+    if( opts&opt_write_add_args )
+    {
+      vars.push_back( ((SymSExpr*)progvars->kids[counter])->s );
+    }
+    counter++;
+  }
+  os << " )";
+  if( opts&opt_write_call_debug )
+  {
+     os << "{" << std::endl;
+     indent( os, 1 );
+     os << "std::cout << \"Call function " << fname.c_str() << " with arguments \";" << std::endl;
+     counter = 0; 
+     while( progvars->kids[counter] )
+     {
+        if( counter!=0 )
+        {
+           indent( os, 1 );
+           os << "std::cout << \", \";" << std::endl;
+        }
+        indent( os, 1 );
+        write_variable( ((SymSExpr*)progvars->kids[counter])->s, os );
+        os << "->print( std::cout );" << std::endl;
+        counter++;
+     }
+     indent( os, 1 );
+     os << "std::cout << std::endl;" << std::endl;
+  }
+}
+
+void sccwriter::get_function_name( const std::string& pname, std::string& fname )
+{
+  fname = std::string( "f_" );
+  fname.append( pname );
+}
+
+void sccwriter::write_variable( const std::string& n, std::ostream& os )
+{
+  std::string nn;
+  get_var_name( n, nn );
+  os << nn.c_str();
+}
+
+void sccwriter::get_var_name( const std::string& n, std::string& nn ) {
+  nn = std::string( n.c_str() );
+  for( int i = 0; i <(int)n.length(); i++ ){
+    char c = n[i];
+    if (c <= 47)
+        c += 65;
+    else if (c >= 58 && c <= 64)
+        c += 97-58;
+    if ((c >= 91 && c <= 94) || c == 96)
+        c += 104-91;
+    else if (c >= 123)
+        c -= 4;
+    nn[i] = c;
+  }  
+}
+
+void sccwriter::write_file()
+{
+  static std::string filename( "scccode" );
+
+  //writer the h file
+  std::fstream fsh;
+  std::string fnameh( filename );
+  fnameh.append(".h");
+  fsh.open( fnameh.c_str(), std::ios::out );
+  //write the header in h
+  fsh << "#ifndef SCC_CODE_H" << std::endl;
+  fsh << "#define SCC_CODE_H" << std::endl << std::endl;
+  //include necessary files in h file
+  fsh << "#include \"check.h\"" << std::endl << std::endl;
+  //write the init function
+  fsh << "void init_compiled_scc();" << std::endl << std::endl;
+  //write the entry function
+  fsh << "Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args );" << std::endl << std::endl;
+  //write the side condition code functions
+  for( int n=0; n<(int)progs.size(); n++ )
+  {
+    //write the header in the h file
+    fsh << "inline ";
+    write_function_header( fsh, n );
+    fsh << ";" << std::endl << std::endl;
+  }
+  fsh << "#endif" << std::endl << std::endl;
+  fsh.close();
+
+
+  //writer the cpp code
+  std::fstream fsc;
+  std::string fnamec( filename );
+  fnamec.append(".cpp");
+  fsc.open( fnamec.c_str(), std::ios::out );
+  //include the h file in the cpp
+  fsc << "#include \"scccode.h\"" << std::endl << std::endl;
+  std::ostringstream fsc_funcs;
+  //write the side condition code functions
+  for( currProgram=0; currProgram<(int)progs.size(); currProgram++ )
+  {
+    //reset naming counters
+    vars.clear();
+    exprCount = 0;
+    strCount = 0;
+    argsCount = 0;
+    rnumCount = 0;
+
+    //for debugging
+    std::cout << "program #" << currProgram << " " << progNames[currProgram].c_str() << std::endl;
+
+    //write the function header
+    write_function_header( fsc_funcs, currProgram, opt_write_add_args|options );
+    if( (options&opt_write_call_debug)==0 )
+    {
+       fsc_funcs << "{" << std::endl;
+    }
+    //write the code
+    //std::vector< std::string > cleanVec;
+    //write_code( get_prog( n )->kids[2], fsc, 1, "return ", cleanVec );
+    //debug_write_code( progs[n].second->kids[2], fsc, 1 );
+    std::string expr;
+    write_expr( get_prog( currProgram )->kids[2], fsc_funcs, 1, expr );
+    indent( fsc_funcs, 1 );
+    fsc_funcs << "return " << expr.c_str() << ";" << std::endl;
+    fsc_funcs << "}" << std::endl << std::endl;
+  }
+  //write the predefined symbols necessary - symbols and progs
+  for( int a=0; a<(int)globalSyms.size(); a++ )
+  {
+    fsc << "Expr* e_" << globalSyms[a].c_str() << ";" << std::endl;
+  }
+  for( int a=0; a<(int)progs.size(); a++ )
+  {
+    fsc << "Expr* e_" << progNames[a].c_str() << ";" << std::endl;
+  }
+  fsc << std::endl;
+  //write the init function - initialize symbols and progs
+  fsc << "void init_compiled_scc(){" << std::endl;
+  for( int a=0; a<(int)globalSyms.size(); a++ )
+  {
+    indent( fsc, 1 );
+    fsc << "e_" << globalSyms[a].c_str() << " = symbols->get(\"" << globalSyms[a].c_str() << "\").first;" << std::endl;
+  }
+  for( int a=0; a<(int)progs.size(); a++ )
+  {
+    indent( fsc, 1 );
+    fsc << "e_" << progNames[a].c_str() << " = progs[\"" << progNames[a].c_str() << "\"];" << std::endl;
+  }
+  fsc << "}" << std::endl << std::endl;
+  fsc << "Expr* run_compiled_scc( Expr* p, std::vector< Expr* >& args ){" << std::endl;
+  //for( int n=0; n<(int)progs.size(); n++ ){
+  //  indent( fsc, 1 );
+  //  fsc << "static std::string s_" << progNames[n].c_str() << " = std::string( \"" << progNames[n].c_str() << "\" );" << std::endl;
+  //}
+  for( int n=0; n<(int)progs.size(); n++ ){
+    indent( fsc, 1 );
+    if( n!=0 ){
+      fsc << "}else ";
+    }
+    //for each function, test to see if the string matches the name of the function
+    fsc << "if( p==e_" << progNames[n].c_str() << " ){" << std::endl;
+    indent( fsc, 2 );
+    std::string fname;
+    get_function_name( progNames[n], fname );
+    //map the function to the proper function
+    fsc << "return " << fname.c_str() << "( ";
+    //write the arguments to the function from args
+    CExpr* progvars = (CExpr*)get_prog( n )->kids[1];
+    int counter = 0;
+    bool firstTime = true;
+    while( progvars->kids[counter] )
+    {
+      if( !firstTime )
+      {
+        fsc << ", ";
+      }
+      fsc << "args[" << counter << "]";
+      firstTime = false;
+      counter++;
+    }
+    fsc << " );" << std::endl;
+  }
+  indent( fsc, 1 );
+  fsc << "}else{" << std::endl;
+  indent( fsc, 2 );
+  //return null in the case the function could not be found
+  fsc << "return NULL;" << std::endl;
+  indent( fsc, 1 );
+  fsc << "}" << std::endl;
+  fsc << "}" << std::endl << std::endl;
+  fsc << fsc_funcs.str().c_str();
+
+  fsc.close();
+}
+
+void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* retModStr, int opts )
+{
+  std::string retModString;
+  std::string incString;
+  if ( retModStr )
+  {
+    retModString = std::string( retModStr );
+    retModString.append( " = " );
+    incString = std::string( retModStr );
+    incString.append( "->inc();" );
+  }
+  switch( code->getclass() )
+  {
+  case INT_EXPR:
+    {
+      indent( os, ind );
+      os << retModString.c_str();
+      os << "new IntExpr( " << mpz_get_si( ((IntExpr*)code)->n ) << " );" << std::endl;
+      indent( os, ind );
+      os << incString.c_str() << std::endl;
+    }
+    break;
+  case RAT_EXPR:
+    {
+      mpz_t num, den;
+      mpz_init(num);
+      mpz_init(den);
+      mpq_get_num( num, ((RatExpr*)code)->n );
+      mpq_get_den( den, ((RatExpr*)code)->n );
+      indent( os, ind );
+      os << retModString.c_str();
+      os << "new RatExpr( " << mpz_get_si( num ) << ", " << mpz_get_si( den ) << " );" << std::endl;
+      indent( os, ind );
+      os << incString.c_str() << std::endl;
+    }
+    break;
+  case SYMS_EXPR:
+    {
+      //if it is a variable, simply write it to buffer
+      if( is_var( ((SymSExpr*)code)->s ) )
+      {
+        indent( os, ind );
+        os << retModString.c_str();
+        write_variable( ((SymSExpr*)code)->s.c_str(), os );
+        os << ";" << std::endl;  
+      }
+      else  //else must look at symbol lookup table
+      {
+        std::string var;
+        get_var_name( ((SymSExpr*)code)->s, var );
+        indent( os, ind );
+        os << retModString.c_str() << "e_" << var.c_str() << ";" << std::endl;
+        add_global_sym( var ); 
+      }
+      indent( os, ind );
+      os << incString.c_str() << std::endl;
+    }
+    break;
+  default:
+    switch( code->getop() )
+    {
     case APP:
       {
         //collect the arguments
@@ -403,7 +403,7 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
           //os << expr.c_str() << "->dec();" << std::endl;
         }
       }
-      break;\r
+      break;
     case MATCH:
       {
         //calculate the value for the expression
@@ -565,13 +565,13 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         if( retModStr!=NULL ){
           indent( os, ind );
           os << retModString.c_str() << expr.c_str() << ";" << std::endl;
-          indent( os, ind );\r
+          indent( os, ind );
           os << incString.c_str() << std::endl;
         }
         write_dec( expr, os, ind );
       }
       break;
-    case IFMARKED:\r
+    case IFMARKED:
       {
         //calculate the value for the expression
         std::string expr;
@@ -585,10 +585,10 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         os << "}else{" << std::endl;
         write_code( ((CExpr*)code)->kids[2], os, ind+1, retModStr );
         indent( os, ind );
-        os << "}" << std::endl;\r
-        //clean up memory\r
-        write_dec( expr, os, ind );\r
-      }\r
+        os << "}" << std::endl;
+        //clean up memory
+        write_dec( expr, os, ind );
+      }
       break;
 #else
     case MARKVAR:
@@ -612,7 +612,7 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         if( retModStr!=NULL ){
           indent( os, ind );
           os << retModString.c_str() << expr.c_str() << ";" << std::endl;
-          indent( os, ind );\r
+          indent( os, ind );
           os << incString.c_str() << std::endl;
         }
         write_dec( expr, os, ind );
@@ -631,12 +631,12 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         write_code( ((CExpr*)code)->kids[3], os, ind+1, retModStr );
         indent( os, ind );
         os << "}" << std::endl;
-        //clean up memory\r
+        //clean up memory
         write_dec( expr1, os, ind );
         write_dec( expr2, os, ind );
       }
       break;
-    case IFMARKED:\r
+    case IFMARKED:
       {
         //calculate the value for the expression
         std::string expr;
@@ -651,10 +651,10 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         os << "}else{" << std::endl;
         write_code( ((CExpr*)code)->kids[3], os, ind+1, retModStr );
         indent( os, ind );
-        os << "}" << std::endl;\r
-        //clean up memory\r
-        write_dec( expr, os, ind );\r
-      }\r
+        os << "}" << std::endl;
+        //clean up memory
+        write_dec( expr, os, ind );
+      }
       break;
 #endif
     case ADD:
@@ -709,8 +709,8 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         write_dec( expr2, os, ind );
       }
       break;
-    case NEG:\r
-      {\r
+    case NEG:
+      {
         //calculate the value for the first expression
         std::string expr1;
         write_expr( ((CExpr*)code)->kids[0], os, ind, expr1 );
@@ -726,9 +726,9 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         indent( os, ind+1 );
         os << "mpz_neg( " << ss.str().c_str() << ", ((IntExpr*)" << expr1.c_str() << "->followDefs())->n );" << std::endl;
         indent( os, ind+1 );
-        os << retModString.c_str() << "new IntExpr(" << ss.str().c_str() << ");" << std::endl;\r
+        os << retModString.c_str() << "new IntExpr(" << ss.str().c_str() << ");" << std::endl;
         indent( os, ind );
-        os << "}else if( " << expr1.c_str() << "->followDefs()->getclass()==RAT_EXPR ){" << std::endl;\r
+        os << "}else if( " << expr1.c_str() << "->followDefs()->getclass()==RAT_EXPR ){" << std::endl;
         indent( os, ind+1 );
         os << "mpq_t " << ss.str().c_str() << ";" << std::endl;
         indent( os, ind+1 );
@@ -736,55 +736,55 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
         indent( os, ind+1 );
         os << "mpq_neg( " << ss.str().c_str() << ", ((RatExpr*)" << expr1.c_str() << "->followDefs())->n );" << std::endl;
         indent( os, ind+1 );
-        os << retModString.c_str() << "new RatExpr(" << ss.str().c_str() << ");" << std::endl;\r
+        os << retModString.c_str() << "new RatExpr(" << ss.str().c_str() << ");" << std::endl;
         indent( os, ind );
-        os << "}" << std::endl;\r
-        //clean up memory\r
-        write_dec( expr1, os, ind );\r
-      }\r
-      break;\r
-    case IFNEG:\r
-    case IFZERO:\r
-      {\r
+        os << "}" << std::endl;
+        //clean up memory
+        write_dec( expr1, os, ind );
+      }
+      break;
+    case IFNEG:
+    case IFZERO:
+      {
         std::string expr1;
-        write_expr( ((CExpr*)code)->kids[0], os, ind, expr1 );\r
+        write_expr( ((CExpr*)code)->kids[0], os, ind, expr1 );
         indent( os, ind );
-        os << "if( " << expr1.c_str() << "->followDefs()->getclass()==INT_EXPR ){" << std::endl;\r
-        indent( os, ind+1 );\r
-        os << "if( mpz_sgn( ((IntExpr *)" << expr1.c_str() << "->followDefs())->n ) ";\r
-        if( code->getop()==IFNEG )\r
-          os << "<";\r
-        else\r
-          os << "==";\r
-        os << " 0 ){" << std::endl;\r
-        write_code( ((CExpr*)code)->kids[1], os, ind+2, retModStr );\r
-        indent( os, ind+1 );\r
-        os << "}else{" << std::endl;\r
-        write_code( ((CExpr*)code)->kids[2], os, ind+2, retModStr );\r
-        indent( os, ind+1 );\r
-        os << "}" << std::endl;\r
+        os << "if( " << expr1.c_str() << "->followDefs()->getclass()==INT_EXPR ){" << std::endl;
+        indent( os, ind+1 );
+        os << "if( mpz_sgn( ((IntExpr *)" << expr1.c_str() << "->followDefs())->n ) ";
+        if( code->getop()==IFNEG )
+          os << "<";
+        else
+          os << "==";
+        os << " 0 ){" << std::endl;
+        write_code( ((CExpr*)code)->kids[1], os, ind+2, retModStr );
+        indent( os, ind+1 );
+        os << "}else{" << std::endl;
+        write_code( ((CExpr*)code)->kids[2], os, ind+2, retModStr );
+        indent( os, ind+1 );
+        os << "}" << std::endl;
         indent( os, ind );
-        os << "}else if( " << expr1.c_str() << "->followDefs()->getclass()==RAT_EXPR ){" << std::endl;\r
-        indent( os, ind+1 );\r
-        os << "if( mpq_sgn( ((RatExpr *)" << expr1.c_str() << "->followDefs())->n ) ";\r
-        if( code->getop()==IFNEG )\r
-          os << "<";\r
-        else\r
-          os << "==";\r
-        os << " 0 ){" << std::endl;\r
-        write_code( ((CExpr*)code)->kids[1], os, ind+2, retModStr );\r
-        indent( os, ind+1 );\r
-        os << "}else{" << std::endl;\r
-        write_code( ((CExpr*)code)->kids[2], os, ind+2, retModStr );\r
-        indent( os, ind+1 );\r
-        os << "}" << std::endl;\r
+        os << "}else if( " << expr1.c_str() << "->followDefs()->getclass()==RAT_EXPR ){" << std::endl;
+        indent( os, ind+1 );
+        os << "if( mpq_sgn( ((RatExpr *)" << expr1.c_str() << "->followDefs())->n ) ";
+        if( code->getop()==IFNEG )
+          os << "<";
+        else
+          os << "==";
+        os << " 0 ){" << std::endl;
+        write_code( ((CExpr*)code)->kids[1], os, ind+2, retModStr );
+        indent( os, ind+1 );
+        os << "}else{" << std::endl;
+        write_code( ((CExpr*)code)->kids[2], os, ind+2, retModStr );
+        indent( os, ind+1 );
+        os << "}" << std::endl;
         indent( os, ind );
-        os << "}" << std::endl;\r
-        //clean up memory\r
-        write_dec( expr1, os, ind );\r
-      }\r
-      break;\r
-    case RUN:/*?*/break;\r
+        os << "}" << std::endl;
+        //clean up memory
+        write_dec( expr1, os, ind );
+      }
+      break;
+    case RUN:/*?*/break;
     case PI:/*?*/break;
     case LAM:/*?*/break;
     case TYPE:/*?*/break;
@@ -793,16 +793,16 @@ void sccwriter::write_code( Expr* code, std::ostream& os, int ind, const char* r
     case MPZ:/*?*/break;
     case PROG:/*?*/break;
     case PROGVARS:/*?*/break;
-    case PAT:/*?*/break;\r
-    }\r
-    break;\r
-  }\r
-}\r
-\r
-void sccwriter::write_args( CExpr* code, std::ostream& os, int ind, int childCounter, \r
-                            std::vector< std::string >& args, int opts )\r
-{\r
-  bool encounterCase = false;\r
+    case PAT:/*?*/break;
+    }
+    break;
+  }
+}
+
+void sccwriter::write_args( CExpr* code, std::ostream& os, int ind, int childCounter, 
+                            std::vector< std::string >& args, int opts )
+{
+  bool encounterCase = false;
   while( code->kids[childCounter] &&
          (!encounterCase || code->kids[childCounter]->getop()==CASE ) )
   {
@@ -819,68 +819,68 @@ void sccwriter::write_args( CExpr* code, std::ostream& os, int ind, int childCou
       args.push_back( expr );
     }
     childCounter++;
-  }\r
-}\r
-\r
-void sccwriter::write_expr( Expr* code, std::ostream& os, int ind, std::string& expr, int opts )\r
-{\r
-  if( code->getclass()==SYMS_EXPR && is_var( ((SymSExpr*)code)->s ) )\r
-  {\r
-    get_var_name( ((SymSExpr*)code)->s, expr );\r
-    indent( os, ind );\r
-    os << expr.c_str() << "->inc();" << std::endl;\r
-  }\r
-  else\r
-  {\r
+  }
+}
+
+void sccwriter::write_expr( Expr* code, std::ostream& os, int ind, std::string& expr, int opts )
+{
+  if( code->getclass()==SYMS_EXPR && is_var( ((SymSExpr*)code)->s ) )
+  {
+    get_var_name( ((SymSExpr*)code)->s, expr );
+    indent( os, ind );
+    os << expr.c_str() << "->inc();" << std::endl;
+  }
+  else
+  {
     std::ostringstream ss;
     ss << "e" << exprCount;
-    exprCount++;\r
-    //declare the expression\r
-    indent( os, ind );\r
-    if( code->getclass()==SYMS_EXPR && !is_var( ((SymSExpr*)code)->s ) )\r
-    {\r
-      os << "static ";\r
-    }\r
-    os << "Expr* " << ss.str().c_str() << ";" << std::endl;\r
-    //write the expression\r
+    exprCount++;
+    //declare the expression
+    indent( os, ind );
+    if( code->getclass()==SYMS_EXPR && !is_var( ((SymSExpr*)code)->s ) )
+    {
+      os << "static ";
+    }
+    os << "Expr* " << ss.str().c_str() << ";" << std::endl;
+    //write the expression
     std::ostringstream ss2;
     ss2 << ss.str().c_str();
-    write_code( code, os, ind, ss2.str().c_str(), opts );\r
-\r
-    //if is not a sym expression, then decrement the expression and return null\r
-    if( opts&opt_write_check_sym_expr )\r
+    write_code( code, os, ind, ss2.str().c_str(), opts );
+
+    //if is not a sym expression, then decrement the expression and return null
+    if( opts&opt_write_check_sym_expr )
     {
       indent( os, ind );
       os << "if (" << expr.c_str() << "->getclass() != SYM_EXPR) {" << std::endl;
       indent( os, ind+1 );
       os << "exit( 1 );" << std::endl;
       indent( os, ind );
-      os << "}" << std::endl;\r
-    }\r
-\r
-    expr = std::string( ss.str().c_str() );\r
-    vars.push_back( expr );\r
-  }\r
-  //increment the counter for memory management\r
-  //indent( os, ind );\r
-  //os << expr.c_str() << "->inc();" << std::endl;\r
-}\r
-\r
-void sccwriter::write_dec( const std::string& expr, std::ostream& os, int ind )\r
-{\r
-  bool wd = true;\r
-  if( wd )\r
-  {\r
-    indent( os, ind );\r
-    os << expr.c_str() << "->dec();" << std::endl;\r
-  }\r
-}\r
-\r
-void sccwriter::debug_write_code( Expr* code, std::ostream& os, int ind )\r
-{\r
-  indent( os, ind );\r
-  switch( code->getclass() )\r
-  {\r
+      os << "}" << std::endl;
+    }
+
+    expr = std::string( ss.str().c_str() );
+    vars.push_back( expr );
+  }
+  //increment the counter for memory management
+  //indent( os, ind );
+  //os << expr.c_str() << "->inc();" << std::endl;
+}
+
+void sccwriter::write_dec( const std::string& expr, std::ostream& os, int ind )
+{
+  bool wd = true;
+  if( wd )
+  {
+    indent( os, ind );
+    os << expr.c_str() << "->dec();" << std::endl;
+  }
+}
+
+void sccwriter::debug_write_code( Expr* code, std::ostream& os, int ind )
+{
+  indent( os, ind );
+  switch( code->getclass() )
+  {
   case INT_EXPR:
     os << "int_expr";
     break;
@@ -890,12 +890,12 @@ void sccwriter::debug_write_code( Expr* code, std::ostream& os, int ind )
   case SYM_EXPR:
     os << "sym_expr";
     break;
-  case SYMS_EXPR:\r
-    os << "syms_expr: " << ((SymSExpr*)code)->s.c_str();\r
-    break;\r
-  default:\r
-    switch( code->getop() )\r
-    {\r
+  case SYMS_EXPR:
+    os << "syms_expr: " << ((SymSExpr*)code)->s.c_str();
+    break;
+  default:
+    switch( code->getop() )
+    {
     case APP:
       os << "app";
       break;
@@ -920,9 +920,9 @@ void sccwriter::debug_write_code( Expr* code, std::ostream& os, int ind )
     case PROG:
       os << "prog";
       break;
-    case PROGVARS:\r
-      os << "progvars";\r
-      break;\r
+    case PROGVARS:
+      os << "progvars";
+      break;
     case MATCH:
       os << "match";
       break;
@@ -953,25 +953,25 @@ void sccwriter::debug_write_code( Expr* code, std::ostream& os, int ind )
     case MARKVAR:
       os << "markvar";
       break;
-    case IFMARKED:\r
-      os << "ifmarked";\r
-      break;\r
-    case COMPARE:\r
-      os << "compare";\r
-      break;\r
-    default:\r
-      os << "???";\r
-      break;\r
-    }\r
-  }\r
-  os << std::endl;\r
-  if( code->getop()!=0 )\r
-  {\r
-    CExpr* ce = (CExpr*)code;\r
-    int counter = 0;\r
-    while( ce->kids[counter] ){\r
-      debug_write_code( ce->kids[counter], os, ind+1 );\r
-      counter++;\r
-    }\r
-  }\r
-}\r
+    case IFMARKED:
+      os << "ifmarked";
+      break;
+    case COMPARE:
+      os << "compare";
+      break;
+    default:
+      os << "???";
+      break;
+    }
+  }
+  os << std::endl;
+  if( code->getop()!=0 )
+  {
+    CExpr* ce = (CExpr*)code;
+    int counter = 0;
+    while( ce->kids[counter] ){
+      debug_write_code( ce->kids[counter], os, ind+1 );
+      counter++;
+    }
+  }
+}
index f8922934f5130256a49979bd7dae08669936178e..bd973257992dc71dc6fd6ef2f586055e3e622f0b 100644 (file)
@@ -1,86 +1,86 @@
-#ifndef SCC_WRITER_H\r
-#define SCC_WRITER_H\r
-\r
-#include "expr.h"\r
-#include <vector>\r
-#include "check.h"\r
-\r
-enum\r
-{\r
-  opt_write_case_body = 0x00000001,\r
-  opt_write_check_sym_expr = 0x00000002,\r
-  opt_write_add_args = 0x000000004,\r
-  opt_write_no_inc = 0x00000008,\r
-\r
-  opt_write_call_debug = 0x00000010,\r
-  opt_write_nested_app = 0x00000020,\r
-};\r
-\r
-class sccwriter\r
-{\r
-private:\r
-  //options\r
-   int options;\r
-  //programs to write to file\r
-  symmap progs;\r
-  //list of indicies in progs\r
-  std::vector< Expr* > progPtrs;\r
-  std::vector< std::string > progNames;\r
-  int currProgram;\r
-  //current variables in the scope\r
-  std::vector< std::string > vars;\r
-  //global variables stored for lookups\r
-  std::vector< std::string > globalSyms;\r
-  //symbols that must be dec'ed\r
-  std::vector< std::string > decSyms;\r
-  //get program\r
-  CExpr* get_prog( int n ) { return (CExpr*)progs[ progNames[n] ]; }\r
-  //get index for string\r
-  int get_prog_index_by_expr( Expr* e );\r
-  int get_prog_index( const std::string& str );\r
-  //is variable in current scope\r
-  bool is_var( const std::string& str );\r
-  //add global sym\r
-  void add_global_sym( const std::string& str );\r
-  //expression count\r
-  static int exprCount;\r
-  //string count\r
-  static int strCount;\r
-  //args count\r
-  static int argsCount;\r
-  //num count\r
-  static int rnumCount;\r
-  //indent\r
-  static void indent( std::ostream& os, int ind );\r
-  //write function header\r
-  void write_function_header( std::ostream& os, int index, int opts = 0 );\r
-  void write_code( Expr* code, std::ostream& os, int ind, const char* retModStr, int opts = 0 );\r
-  //write all children starting at child counter to stream, store in Expr* e_...e_;\r
-  void write_args( CExpr* code, std::ostream& os, int ind, int childCounter, std::vector< std::string >& args, int opts = 0 );\r
-  //write expression - store result of code into e_ for some Expr* e_;\r
-  void write_expr( Expr* code, std::ostream& os, int ind, std::string& expr, int opts = 0 );\r
-  //write variable\r
-  void write_variable( const std::string& n, std::ostream& os );\r
-  //get function name\r
-  void get_function_name( const std::string& pname, std::string& fname );\r
-  //get the variable name\r
-  void get_var_name( const std::string& n, std::string& nn );\r
-  //write dec\r
-  void write_dec( const std::string& expr, std::ostream& os, int ind );\r
-public:\r
-  sccwriter( int opts = 0 ) : options( opts ){}\r
-  virtual ~sccwriter(){}\r
-\r
-  void add_scc( const std::string& pname, Expr* exp ) { \r
-    //progs.push_back( std::pair< std::string, CExpr* >( pname, exp ) ); \r
-    progs[pname] = exp;\r
-    progPtrs.push_back( exp );\r
-    progNames.push_back( pname );\r
-  }\r
-\r
-  void write_file();\r
-  //write code\r
-  static void debug_write_code( Expr* code, std::ostream& os, int ind );\r
-};\r
-\r
-#endif\r
+#ifndef SCC_WRITER_H
+#define SCC_WRITER_H
+
+#include "expr.h"
+#include <vector>
+#include "check.h"
+
+enum
+{
+  opt_write_case_body = 0x00000001,
+  opt_write_check_sym_expr = 0x00000002,
+  opt_write_add_args = 0x000000004,
+  opt_write_no_inc = 0x00000008,
+
+  opt_write_call_debug = 0x00000010,
+  opt_write_nested_app = 0x00000020,
+};
+
+class sccwriter
+{
+private:
+  //options
+   int options;
+  //programs to write to file
+  symmap progs;
+  //list of indicies in progs
+  std::vector< Expr* > progPtrs;
+  std::vector< std::string > progNames;
+  int currProgram;
+  //current variables in the scope
+  std::vector< std::string > vars;
+  //global variables stored for lookups
+  std::vector< std::string > globalSyms;
+  //symbols that must be dec'ed
+  std::vector< std::string > decSyms;
+  //get program
+  CExpr* get_prog( int n ) { return (CExpr*)progs[ progNames[n] ]; }
+  //get index for string
+  int get_prog_index_by_expr( Expr* e );
+  int get_prog_index( const std::string& str );
+  //is variable in current scope
+  bool is_var( const std::string& str );
+  //add global sym
+  void add_global_sym( const std::string& str );
+  //expression count
+  static int exprCount;
+  //string count
+  static int strCount;
+  //args count
+  static int argsCount;
+  //num count
+  static int rnumCount;
+  //indent
+  static void indent( std::ostream& os, int ind );
+  //write function header
+  void write_function_header( std::ostream& os, int index, int opts = 0 );
+  void write_code( Expr* code, std::ostream& os, int ind, const char* retModStr, int opts = 0 );
+  //write all children starting at child counter to stream, store in Expr* e_...e_;
+  void write_args( CExpr* code, std::ostream& os, int ind, int childCounter, std::vector< std::string >& args, int opts = 0 );
+  //write expression - store result of code into e_ for some Expr* e_;
+  void write_expr( Expr* code, std::ostream& os, int ind, std::string& expr, int opts = 0 );
+  //write variable
+  void write_variable( const std::string& n, std::ostream& os );
+  //get function name
+  void get_function_name( const std::string& pname, std::string& fname );
+  //get the variable name
+  void get_var_name( const std::string& n, std::string& nn );
+  //write dec
+  void write_dec( const std::string& expr, std::ostream& os, int ind );
+public:
+  sccwriter( int opts = 0 ) : options( opts ){}
+  virtual ~sccwriter(){}
+
+  void add_scc( const std::string& pname, Expr* exp ) { 
+    //progs.push_back( std::pair< std::string, CExpr* >( pname, exp ) ); 
+    progs[pname] = exp;
+    progPtrs.push_back( exp );
+    progNames.push_back( pname );
+  }
+
+  void write_file();
+  //write code
+  static void debug_write_code( Expr* code, std::ostream& os, int ind );
+};
+
+#endif
index 02cadaeab43b79cf42a52dfef0890db37935e8ed..ae585e455efe35d62328ac224a0fb27827d1625e 100755 (executable)
@@ -1,57 +1,57 @@
-; a = b ^ a = 00000 ^ b = 11111 is UNSAT\r
-\r
-(check\r
-(% a var_bv\r
-(% b var_bv\r
-(% f1 (th_holds (= BitVec (a_var_bv a) (a_var_bv b)))\r
-(% f2 (th_holds (= BitVec (a_var_bv a) (a_bv (bvc b0 (bvc b0 (bvc b0 (bvc b0 (bvc b0 bvn))))))))\r
-(% f3 (th_holds (= BitVec (a_var_bv b) (a_bv (bvc b1 (bvc b1 (bvc b1 (bvc b1 (bvc b1 bvn))))))))\r
-(: (holds cln)\r
-\r
-(decl_bv_atom_var 5 a (\ ba1\r
-(decl_bv_atom_var 5 b (\ ba2\r
-(decl_bv_atom_const _ (bvc b0 (bvc b0 (bvc b0 (bvc b0 (bvc b0 bvn))))) (\ c (\ ba3\r
-(decl_bv_atom_const _ (bvc b1 (bvc b1 (bvc b1 (bvc b1 (bvc b1 bvn))))) (\ d (\ ba4\r
-\r
-(decl_atom (bblast a 4) (\ v1 (\ a1\r
-(decl_atom (bblast b 4) (\ v2 (\ a2\r
-\r
-; bitblasting terms\r
-(th_let_pf _ (bv_bbl_var _ _ _ ba1) (\ bt1\r
-(th_let_pf _ (bv_bbl_var _ _ _ ba2) (\ bt2\r
-(th_let_pf _ (bv_bbl_const _ _ _ _ ba3) (\ bt3\r
-(th_let_pf _ (bv_bbl_const _ _ _ _ ba4) (\ bt4\r
-\r
-; bitblasting formulas\r
-(th_let_pf _ (bv_bbl_eq _ _ _ _ _ bt1 bt2) (\ bf1\r
-(th_let_pf _ (bv_bbl_eq _ _ _ _ _ bt1 bt3) (\ bf2\r
-(th_let_pf _ (bv_bbl_eq _ _ _ _ _ bt2 bt4) (\ bf3\r
-\r
-; CNFication\r
-; a.4 V ~b.4\r
-(satlem _ _\r
-(asf _ _ _ a1 (\ l1\r
-(ast _ _ _ a2 (\ l2\r
-(clausify_false\r
-  (contra _ (impl_elim _ _ l2 (iff_elim_2 _ _ (and_elim_1 _ _ (impl_elim _ _ f1 bf1)))) l1)   ; notice at the intermost we impl_elim, which converts from atom to bit-blasting representation\r
-))))) (\ C2\r
-\r
-; ~a.4\r
-(satlem _ _\r
-(ast _ _ _ a1 (\ l1\r
-(clausify_false\r
-  (impl_elim _ _ l1 (iff_elim_1 _ _ (and_elim_1 _ _ (impl_elim _ _ f2 bf2))))\r
-))) (\ C3\r
-\r
-; b.4 \r
-(satlem _ _\r
-(asf _ _ _ a2 (\ l2\r
-(clausify_false\r
-  (contra _ (impl_elim _ _ truth (iff_elim_2 _ _ (and_elim_1 _ _ (impl_elim _ _ f3 bf3)))) l2)\r
-))) (\ C6\r
-\r
-\r
-(satlem_simplify _ _ _ \r
-(R _ _ (R _ _ C6 C2 v2) C3 v1) (\ x x))\r
-\r
+; a = b ^ a = 00000 ^ b = 11111 is UNSAT
+
+(check
+(% a var_bv
+(% b var_bv
+(% f1 (th_holds (= BitVec (a_var_bv a) (a_var_bv b)))
+(% f2 (th_holds (= BitVec (a_var_bv a) (a_bv (bvc b0 (bvc b0 (bvc b0 (bvc b0 (bvc b0 bvn))))))))
+(% f3 (th_holds (= BitVec (a_var_bv b) (a_bv (bvc b1 (bvc b1 (bvc b1 (bvc b1 (bvc b1 bvn))))))))
+(: (holds cln)
+
+(decl_bv_atom_var 5 a (\ ba1
+(decl_bv_atom_var 5 b (\ ba2
+(decl_bv_atom_const _ (bvc b0 (bvc b0 (bvc b0 (bvc b0 (bvc b0 bvn))))) (\ c (\ ba3
+(decl_bv_atom_const _ (bvc b1 (bvc b1 (bvc b1 (bvc b1 (bvc b1 bvn))))) (\ d (\ ba4
+
+(decl_atom (bblast a 4) (\ v1 (\ a1
+(decl_atom (bblast b 4) (\ v2 (\ a2
+
+; bitblasting terms
+(th_let_pf _ (bv_bbl_var _ _ _ ba1) (\ bt1
+(th_let_pf _ (bv_bbl_var _ _ _ ba2) (\ bt2
+(th_let_pf _ (bv_bbl_const _ _ _ _ ba3) (\ bt3
+(th_let_pf _ (bv_bbl_const _ _ _ _ ba4) (\ bt4
+
+; bitblasting formulas
+(th_let_pf _ (bv_bbl_eq _ _ _ _ _ bt1 bt2) (\ bf1
+(th_let_pf _ (bv_bbl_eq _ _ _ _ _ bt1 bt3) (\ bf2
+(th_let_pf _ (bv_bbl_eq _ _ _ _ _ bt2 bt4) (\ bf3
+
+; CNFication
+; a.4 V ~b.4
+(satlem _ _
+(asf _ _ _ a1 (\ l1
+(ast _ _ _ a2 (\ l2
+(clausify_false
+  (contra _ (impl_elim _ _ l2 (iff_elim_2 _ _ (and_elim_1 _ _ (impl_elim _ _ f1 bf1)))) l1)   ; notice at the intermost we impl_elim, which converts from atom to bit-blasting representation
+))))) (\ C2
+
+; ~a.4
+(satlem _ _
+(ast _ _ _ a1 (\ l1
+(clausify_false
+  (impl_elim _ _ l1 (iff_elim_1 _ _ (and_elim_1 _ _ (impl_elim _ _ f2 bf2))))
+))) (\ C3
+
+; b.4 
+(satlem _ _
+(asf _ _ _ a2 (\ l2
+(clausify_false
+  (contra _ (impl_elim _ _ truth (iff_elim_2 _ _ (and_elim_1 _ _ (impl_elim _ _ f3 bf3)))) l2)
+))) (\ C6
+
+
+(satlem_simplify _ _ _ 
+(R _ _ (R _ _ C6 C2 v2) C3 v1) (\ x x))
+
 )))))))))))))))))))))))))))))))))))))))))))
\ No newline at end of file
index 3fb9d13563a7b3afdfee7814ac06f7fe558f5336..0fb50f8cfa8a732942c82bdecb43d16b0824f78d 100755 (executable)
-; "bitvec" is a term of type "sort"\r
-(declare BitVec sort)\r
-\r
-; bit type\r
-(declare bit type)\r
-(declare b0 bit)\r
-(declare b1 bit)\r
-\r
-; bit vector type\r
-(declare bv type)\r
-(declare bvn bv)\r
-(declare bvc (! b bit (! v bv bv)))\r
-; a bv constant term\r
-(declare a_bv (! v bv (term BitVec)))\r
-\r
-; calculate the length of a bitvector\r
-(program bv_len ((v bv)) mpz \r
-  (match v\r
-    (bvn 0)\r
-    ((bvc b v') (mp_add (bv_len v') 1))))\r
-\r
-; a bv variable\r
-(declare var_bv type)\r
-; a bv variable term\r
-(declare a_var_bv (! v var_bv (term BitVec)))\r
-\r
-\r
-; bit vector operators\r
-(define bvoper (! x (term BitVec) \r
-               (! y (term BitVec) \r
-                    (term BitVec))))\r
-(declare bvand bvoper)\r
-(declare bvadd bvoper)\r
-;....\r
-\r
-; all bit-vector terms are mapped with "bv_atom" to:\r
-;  - a simply-typed term of type "var_bv", which is necessary for bit-blasting\r
-;  - a integer size\r
-(declare bv_atom (! x (term BitVec) (! y var_bv (! n mpz type))))\r
-\r
-(declare decl_bv_atom_var (! n mpz    ; must be specified\r
-                          (! x var_bv\r
-                          (! p (! u (bv_atom (a_var_bv x) x n)\r
-                                 (holds cln))\r
-                             (holds cln)))))\r
-\r
-(declare decl_bv_atom_const (! n mpz\r
-                            (! v bv\r
-                            (! s (^ (bv_len v) n)\r
-                            (! p (! w var_bv\r
-                                 (! u (bv_atom (a_bv v) w n)\r
-                                   (holds cln)))\r
-                             (holds cln))))))\r
-\r
-\r
-; other terms here?\r
-\r
-\r
-; bit blasted terms\r
-(declare bblt type)\r
-(declare bbltn bblt)\r
-(declare bbltc (! f formula (! v bblt bblt)))\r
-\r
-; (bblast_term x y) means term x corresponds to bit level interpretation y\r
-(declare bblast_term (! x (term BitVec) (! y bblt formula)))\r
-\r
-; a predicate to represent the n^th bit of a bitvector term\r
-(declare bblast (! x var_bv (! n mpz formula)))\r
-\r
-\r
-; bit blast  constant\r
-(program bblast_const ((v bv) (n mpz)) bblt\r
-  (mp_ifneg n (match v (bvn bbltn) \r
-                       (default (fail bblt)))\r
-              (match v ((bvc b v') (bbltc (match b (b0 false) (b1 true)) (bblast_const v' (mp_add n (~ 1)))))\r
-                       (default (fail bblt)))))\r
-              \r
-(declare bv_bbl_const (! n mpz\r
-                      (! v bv\r
-                      (! x var_bv\r
-                      (! f bblt\r
-                      (! u (bv_atom (a_bv v) x n)\r
-                      (! c (^ (bblast_const v (mp_add n (~ 1))) f)\r
-                         (th_holds (bblast_term (a_bv v) f)))))))))\r
-\r
-; bit blast  variable\r
-(program bblast_var ((x var_bv) (n mpz)) bblt\r
-  (mp_ifneg n bbltn \r
-              (bbltc (bblast x n) (bblast_var x (mp_add n (~ 1))))))\r
-\r
-(declare bv_bbl_var (! n mpz\r
-                    (! x var_bv\r
-                    (! f bblt                    \r
-                    (! u (bv_atom (a_var_bv x) x n)\r
-                    (! c (^ (bblast_var x (mp_add n (~ 1))) f)\r
-                       (th_holds (bblast_term (a_var_bv x) f))))))))\r
-\r
-; bit blast  x = y\r
-;  for x,y of size n, it will return a conjuction (x.{n-1} = y.{n-1} ^ ( ... ^ (x.0 = y.0 ^ true)))\r
-(program bblast_eq ((x bblt) (y bblt)) formula\r
-  (match x \r
-    (bbltn (match y (bbltn true) (default (fail formula))))\r
-    ((bbltc fx x') (match y \r
-                      (bbltn (fail formula))\r
-                      ((bbltc fy y') (and (iff fx fy) (bblast_eq x' y')))))))\r
-\r
-(declare bv_bbl_eq (! x (term BitVec)\r
-                   (! y (term BitVec)\r
-                   (! fx bblt\r
-                   (! fy bblt\r
-                   (! f formula\r
-                   (! ux (th_holds (bblast_term x fx))\r
-                   (! uy (th_holds (bblast_term y fy))\r
-                   (! c (^ (bblast_eq fx fy) f)\r
-                      (th_holds (impl (= BitVec x y) f)))))))))))\r
-\r
-\r
-; rewrite rule :\r
-; x + y = y + x\r
-(declare bvadd_symm (! x (term BitVec)\r
-                    (! y (term BitVec)\r
-                    (! x' var_bv\r
-                    (! y' var_bv\r
-                    (! n mpz\r
-                    (! ux (bv_atom x x' n)\r
-                    (! uy (bv_atom y y' n)\r
-                       (th_holds (= BitVec (bvadd x y) (bvadd y x)))))))))))\r
-\r
-\r
-\r
-; necessary? \r
-(program calc_bvand ((a bv) (b bv)) bv\r
-  (match a\r
-    (bvn (match b (bvn bvn) (default (fail bv))))\r
-    ((bvc ba a') (match b\r
-                      ((bvc bb b') (bvc (match ba (b0 b0) (b1 bb)) (calc_bvand a' b')))\r
-                      (default (fail bv))))))\r
-\r
-; rewrite rule (w constants) :\r
-; a & b = c    \r
-(declare bvand_const (! c bv\r
-                    (! a bv\r
-                     (! b bv\r
-                     (! u (^ (calc_bvand a b) c)\r
+; "bitvec" is a term of type "sort"
+(declare BitVec sort)
+
+; bit type
+(declare bit type)
+(declare b0 bit)
+(declare b1 bit)
+
+; bit vector type
+(declare bv type)
+(declare bvn bv)
+(declare bvc (! b bit (! v bv bv)))
+; a bv constant term
+(declare a_bv (! v bv (term BitVec)))
+
+; calculate the length of a bitvector
+(program bv_len ((v bv)) mpz 
+  (match v
+    (bvn 0)
+    ((bvc b v') (mp_add (bv_len v') 1))))
+
+; a bv variable
+(declare var_bv type)
+; a bv variable term
+(declare a_var_bv (! v var_bv (term BitVec)))
+
+
+; bit vector operators
+(define bvoper (! x (term BitVec) 
+               (! y (term BitVec) 
+                    (term BitVec))))
+(declare bvand bvoper)
+(declare bvadd bvoper)
+;....
+
+; all bit-vector terms are mapped with "bv_atom" to:
+;  - a simply-typed term of type "var_bv", which is necessary for bit-blasting
+;  - a integer size
+(declare bv_atom (! x (term BitVec) (! y var_bv (! n mpz type))))
+
+(declare decl_bv_atom_var (! n mpz    ; must be specified
+                          (! x var_bv
+                          (! p (! u (bv_atom (a_var_bv x) x n)
+                                 (holds cln))
+                             (holds cln)))))
+
+(declare decl_bv_atom_const (! n mpz
+                            (! v bv
+                            (! s (^ (bv_len v) n)
+                            (! p (! w var_bv
+                                 (! u (bv_atom (a_bv v) w n)
+                                   (holds cln)))
+                             (holds cln))))))
+
+
+; other terms here?
+
+
+; bit blasted terms
+(declare bblt type)
+(declare bbltn bblt)
+(declare bbltc (! f formula (! v bblt bblt)))
+
+; (bblast_term x y) means term x corresponds to bit level interpretation y
+(declare bblast_term (! x (term BitVec) (! y bblt formula)))
+
+; a predicate to represent the n^th bit of a bitvector term
+(declare bblast (! x var_bv (! n mpz formula)))
+
+
+; bit blast  constant
+(program bblast_const ((v bv) (n mpz)) bblt
+  (mp_ifneg n (match v (bvn bbltn) 
+                       (default (fail bblt)))
+              (match v ((bvc b v') (bbltc (match b (b0 false) (b1 true)) (bblast_const v' (mp_add n (~ 1)))))
+                       (default (fail bblt)))))
+              
+(declare bv_bbl_const (! n mpz
+                      (! v bv
+                      (! x var_bv
+                      (! f bblt
+                      (! u (bv_atom (a_bv v) x n)
+                      (! c (^ (bblast_const v (mp_add n (~ 1))) f)
+                         (th_holds (bblast_term (a_bv v) f)))))))))
+
+; bit blast  variable
+(program bblast_var ((x var_bv) (n mpz)) bblt
+  (mp_ifneg n bbltn 
+              (bbltc (bblast x n) (bblast_var x (mp_add n (~ 1))))))
+
+(declare bv_bbl_var (! n mpz
+                    (! x var_bv
+                    (! f bblt                    
+                    (! u (bv_atom (a_var_bv x) x n)
+                    (! c (^ (bblast_var x (mp_add n (~ 1))) f)
+                       (th_holds (bblast_term (a_var_bv x) f))))))))
+
+; bit blast  x = y
+;  for x,y of size n, it will return a conjuction (x.{n-1} = y.{n-1} ^ ( ... ^ (x.0 = y.0 ^ true)))
+(program bblast_eq ((x bblt) (y bblt)) formula
+  (match x 
+    (bbltn (match y (bbltn true) (default (fail formula))))
+    ((bbltc fx x') (match y 
+                      (bbltn (fail formula))
+                      ((bbltc fy y') (and (iff fx fy) (bblast_eq x' y')))))))
+
+(declare bv_bbl_eq (! x (term BitVec)
+                   (! y (term BitVec)
+                   (! fx bblt
+                   (! fy bblt
+                   (! f formula
+                   (! ux (th_holds (bblast_term x fx))
+                   (! uy (th_holds (bblast_term y fy))
+                   (! c (^ (bblast_eq fx fy) f)
+                      (th_holds (impl (= BitVec x y) f)))))))))))
+
+
+; rewrite rule :
+; x + y = y + x
+(declare bvadd_symm (! x (term BitVec)
+                    (! y (term BitVec)
+                    (! x' var_bv
+                    (! y' var_bv
+                    (! n mpz
+                    (! ux (bv_atom x x' n)
+                    (! uy (bv_atom y y' n)
+                       (th_holds (= BitVec (bvadd x y) (bvadd y x)))))))))))
+
+
+
+; necessary? 
+(program calc_bvand ((a bv) (b bv)) bv
+  (match a
+    (bvn (match b (bvn bvn) (default (fail bv))))
+    ((bvc ba a') (match b
+                      ((bvc bb b') (bvc (match ba (b0 b0) (b1 bb)) (calc_bvand a' b')))
+                      (default (fail bv))))))
+
+; rewrite rule (w constants) :
+; a & b = c    
+(declare bvand_const (! c bv
+                    (! a bv
+                     (! b bv
+                     (! u (^ (calc_bvand a b) c)
                         (th_holds (= BitVec (bvand (a_bv a) (a_bv b)) (a_bv c))))))))                        
\ No newline at end of file
index 116debb7c1e35900adf7f89078e758759bbfd2f0..4167c3ad9a7b3503eb22ce7d62b5fd4c21043b05 100644 (file)
-/*********************                                                        */\r
-/*! \file conjecture_generator.cpp\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief conjecture generator class\r
- **\r
- **/\r
-\r
-#include "theory/quantifiers/conjecture_generator.h"\r
-#include "theory/theory_engine.h"\r
-#include "theory/quantifiers/options.h"\r
-#include "theory/quantifiers/term_database.h"\r
-#include "theory/quantifiers/trigger.h"\r
-#include "theory/quantifiers/first_order_model.h"\r
-\r
-using namespace CVC4;\r
-using namespace CVC4::kind;\r
-using namespace CVC4::theory;\r
-using namespace CVC4::theory::quantifiers;\r
-using namespace std;\r
-\r
-namespace CVC4 {\r
-\r
-struct sortConjectureScore {\r
-  std::vector< int > d_scores;\r
-  bool operator() (unsigned i, unsigned j) { return d_scores[i]>d_scores[j]; }\r
-};\r
-\r
-\r
-void OpArgIndex::addTerm( ConjectureGenerator * s, TNode n, unsigned index ){\r
-  if( index==n.getNumChildren() ){\r
-    Assert( n.hasOperator() );\r
-    if( std::find( d_ops.begin(), d_ops.end(), n.getOperator() )==d_ops.end() ){\r
-      d_ops.push_back( n.getOperator() );\r
-      d_op_terms.push_back( n );\r
-    }\r
-  }else{\r
-    d_child[s->getTermDatabase()->d_arg_reps[n][index]].addTerm( s, n, index+1 );\r
-  }\r
-}\r
-\r
-Node OpArgIndex::getGroundTerm( ConjectureGenerator * s, std::vector< TNode >& args ) {\r
-  if( d_ops.empty() ){\r
-    for( std::map< TNode, OpArgIndex >::iterator it = d_child.begin(); it != d_child.end(); ++it ){\r
-      std::map< TNode, Node >::iterator itf = s->d_ground_eqc_map.find( it->first );\r
-      if( itf!=s->d_ground_eqc_map.end() ){\r
-        args.push_back( itf->second );\r
-        Node n = it->second.getGroundTerm( s, args );\r
-        args.pop_back();\r
-        if( !n.isNull() ){\r
-          return n;\r
-        }\r
-      }\r
-    }\r
-    return Node::null();\r
-  }else{\r
-    std::vector< TNode > args2;\r
-    args2.push_back( d_ops[0] );\r
-    args2.insert( args2.end(), args.begin(), args.end() );\r
-    return NodeManager::currentNM()->mkNode( d_op_terms[0].getKind(), args2 );\r
-  }\r
-}\r
-\r
-void OpArgIndex::getGroundTerms( ConjectureGenerator * s, std::vector< TNode >& terms ) {\r
-  terms.insert( terms.end(), d_op_terms.begin(), d_op_terms.end() );\r
-  for( std::map< TNode, OpArgIndex >::iterator it = d_child.begin(); it != d_child.end(); ++it ){\r
-    if( s->isGroundEqc( it->first ) ){\r
-      it->second.getGroundTerms( s, terms );\r
-    }\r
-  }\r
-}\r
-\r
-\r
-\r
-ConjectureGenerator::ConjectureGenerator( QuantifiersEngine * qe, context::Context* c ) : QuantifiersModule( qe ),\r
-d_notify( *this ),\r
-d_uequalityEngine(d_notify, c, "ConjectureGenerator::ee", false),\r
-d_ee_conjectures( c ){\r
-  d_fullEffortCount = 0;\r
-  d_uequalityEngine.addFunctionKind( kind::APPLY_UF );\r
-  d_uequalityEngine.addFunctionKind( kind::APPLY_CONSTRUCTOR );\r
-\r
-}\r
-\r
-void ConjectureGenerator::eqNotifyNewClass( TNode t ){\r
-  Trace("thm-ee-debug") << "UEE : new equivalence class " << t << std::endl;\r
-  d_upendingAdds.push_back( t );\r
-}\r
-\r
-void ConjectureGenerator::eqNotifyPreMerge(TNode t1, TNode t2) {\r
-  //get maintained representatives\r
-  TNode rt1 = t1;\r
-  TNode rt2 = t2;\r
-  std::map< Node, EqcInfo* >::iterator it1 = d_eqc_info.find( t1 );\r
-  if( it1!=d_eqc_info.end() && !it1->second->d_rep.get().isNull() ){\r
-    rt1 = it1->second->d_rep.get();\r
-  }\r
-  std::map< Node, EqcInfo* >::iterator it2 = d_eqc_info.find( t2 );\r
-  if( it2!=d_eqc_info.end() && !it2->second->d_rep.get().isNull() ){\r
-    rt2 = it2->second->d_rep.get();\r
-  }\r
-  Trace("thm-ee-debug") << "UEE : equality holds : " << t1 << " == " << t2 << std::endl;\r
-  Trace("thm-ee-debug") << "      ureps : " << rt1 << " == " << rt2 << std::endl;\r
-  Trace("thm-ee-debug") << "      relevant : " << d_pattern_is_relevant[rt1] << " " << d_pattern_is_relevant[rt2] << std::endl;\r
-  Trace("thm-ee-debug") << "      normal : " << d_pattern_is_normal[rt1] << " " << d_pattern_is_normal[rt2] << std::endl;\r
-  Trace("thm-ee-debug") << "      size :   " << d_pattern_fun_sum[rt1] << " " << d_pattern_fun_sum[rt2] << std::endl;\r
-\r
-  if( isUniversalLessThan( rt2, rt1 ) ){\r
-    EqcInfo * ei;\r
-    if( it1==d_eqc_info.end() ){\r
-      ei = getOrMakeEqcInfo( t1, true );\r
-    }else{\r
-      ei = it1->second;\r
-    }\r
-    ei->d_rep = t2;\r
-  }\r
-}\r
-\r
-void ConjectureGenerator::eqNotifyPostMerge(TNode t1, TNode t2) {\r
-\r
-}\r
-\r
-void ConjectureGenerator::eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {\r
-  Trace("thm-ee-debug") << "UEE : disequality holds : " << t1 << " != " << t2 << std::endl;\r
-\r
-}\r
-\r
-\r
-ConjectureGenerator::EqcInfo::EqcInfo( context::Context* c ) : d_rep( c, Node::null() ){\r
-\r
-}\r
-\r
-ConjectureGenerator::EqcInfo* ConjectureGenerator::getOrMakeEqcInfo( TNode n, bool doMake ) {\r
-  //Assert( getUniversalRepresentative( n )==n );\r
-  std::map< Node, EqcInfo* >::iterator eqc_i = d_eqc_info.find( n );\r
-  if( eqc_i!=d_eqc_info.end() ){\r
-    return eqc_i->second;\r
-  }else if( doMake ){\r
-    EqcInfo* ei = new EqcInfo( d_quantEngine->getSatContext() );\r
-    d_eqc_info[n] = ei;\r
-    return ei;\r
-  }else{\r
-    return NULL;\r
-  }\r
-}\r
-\r
-void ConjectureGenerator::setUniversalRelevant( TNode n ) {\r
-  //add pattern information\r
-  registerPattern( n, n.getType() );\r
-  d_urelevant_terms[n] = true;\r
-  for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-    setUniversalRelevant( n[i] );\r
-  }\r
-}\r
-\r
-bool ConjectureGenerator::isUniversalLessThan( TNode rt1, TNode rt2 ) {\r
-  //prefer the one that is (normal, smaller) lexographically\r
-  Assert( d_pattern_is_relevant.find( rt1 )!=d_pattern_is_relevant.end() );\r
-  Assert( d_pattern_is_relevant.find( rt2 )!=d_pattern_is_relevant.end() );\r
-  Assert( d_pattern_is_normal.find( rt1 )!=d_pattern_is_normal.end() );\r
-  Assert( d_pattern_is_normal.find( rt2 )!=d_pattern_is_normal.end() );\r
-  Assert( d_pattern_fun_sum.find( rt1 )!=d_pattern_fun_sum.end() );\r
-  Assert( d_pattern_fun_sum.find( rt2 )!=d_pattern_fun_sum.end() );\r
-\r
-  if( d_pattern_is_relevant[rt1] && !d_pattern_is_relevant[rt2] ){\r
-    Trace("thm-ee-debug") << "UEE : LT due to relevant." << std::endl;\r
-    return true;\r
-  }else if( d_pattern_is_relevant[rt1]==d_pattern_is_relevant[rt2] ){\r
-    if( d_pattern_is_normal[rt1] && !d_pattern_is_normal[rt2] ){\r
-      Trace("thm-ee-debug") << "UEE : LT due to normal." << std::endl;\r
-      return true;\r
-    }else if( d_pattern_is_normal[rt1]==d_pattern_is_normal[rt2] ){\r
-      if( d_pattern_fun_sum[rt1]<d_pattern_fun_sum[rt2] ){\r
-        Trace("thm-ee-debug") << "UEE : LT due to size." << std::endl;\r
-        //decide which representative to use : based on size of the term\r
-        return true;\r
-      }else if( d_pattern_fun_sum[rt1]==d_pattern_fun_sum[rt2] ){\r
-        //same size : tie goes to term that has already been reported\r
-        return isReportedCanon( rt1 ) && !isReportedCanon( rt2 );\r
-      }\r
-    }\r
-  }\r
-  return false;\r
-}\r
-\r
-\r
-bool ConjectureGenerator::isReportedCanon( TNode n ) {\r
-  return std::find( d_ue_canon.begin(), d_ue_canon.end(), n )==d_ue_canon.end();\r
-}\r
-\r
-void ConjectureGenerator::markReportedCanon( TNode n ) {\r
-  if( !isReportedCanon( n ) ){\r
-    d_ue_canon.push_back( n );\r
-  }\r
-}\r
-\r
-bool ConjectureGenerator::areUniversalEqual( TNode n1, TNode n2 ) {\r
-  return n1==n2 || ( d_uequalityEngine.hasTerm( n1 ) && d_uequalityEngine.hasTerm( n2 ) && d_uequalityEngine.areEqual( n1, n2 ) );\r
-}\r
-\r
-bool ConjectureGenerator::areUniversalDisequal( TNode n1, TNode n2 ) {\r
-  return n1!=n2 && d_uequalityEngine.hasTerm( n1 ) && d_uequalityEngine.hasTerm( n2 ) && d_uequalityEngine.areDisequal( n1, n2, false );\r
-}\r
-\r
-TNode ConjectureGenerator::getUniversalRepresentative( TNode n, bool add ) {\r
-  if( add ){\r
-    if( d_urelevant_terms.find( n )==d_urelevant_terms.end() ){\r
-      setUniversalRelevant( n );\r
-      //add term to universal equality engine\r
-      d_uequalityEngine.addTerm( n );\r
-      // addding this term to equality engine will lead to a set of new terms (the new subterms of n)\r
-      // now, do instantiation-based merging for each of these terms\r
-      Trace("thm-ee-debug") << "Merge equivalence classes based on instantiations of terms..." << std::endl;\r
-      //merge all pending equalities\r
-      while( !d_upendingAdds.empty() ){\r
-        Trace("sg-pending") << "Add " << d_upendingAdds.size() << " pending terms..." << std::endl;\r
-        std::vector< Node > pending;\r
-        pending.insert( pending.end(), d_upendingAdds.begin(), d_upendingAdds.end() );\r
-        d_upendingAdds.clear();\r
-        for( unsigned i=0; i<pending.size(); i++ ){\r
-          Node t = pending[i];\r
-          TypeNode tn = t.getType();\r
-          Trace("thm-ee-add") << "UEE : Add universal term " << t << std::endl;\r
-          std::vector< Node > eq_terms;\r
-          //if occurs modulo equality at ground level, it is equivalent to representative of ground equality engine\r
-          TNode gt = getTermDatabase()->evaluateTerm( t );\r
-          if( !gt.isNull() && gt!=t ){\r
-            eq_terms.push_back( gt );\r
-          }\r
-          //get all equivalent terms based on theorem database\r
-          d_thm_index.getEquivalentTerms( t, eq_terms );\r
-          if( !eq_terms.empty() ){\r
-            Trace("thm-ee-add") << "UEE : Based on ground EE/theorem DB, it is equivalent to " << eq_terms.size() << " terms : " << std::endl;\r
-            //add equivalent terms as equalities to universal engine\r
-            for( unsigned i=0; i<eq_terms.size(); i++ ){\r
-              Trace("thm-ee-add") << "  " << eq_terms[i] << std::endl;\r
-              bool assertEq = false;\r
-              if( d_urelevant_terms.find( eq_terms[i] )!=d_urelevant_terms.end() ){\r
-                assertEq = true;\r
-              }else{\r
-                Assert( eq_terms[i].getType()==tn );\r
-                registerPattern( eq_terms[i], tn );\r
-                if( isUniversalLessThan( eq_terms[i], t ) || ( options::conjectureUeeIntro() && d_pattern_fun_sum[t]>=d_pattern_fun_sum[eq_terms[i]] ) ){\r
-                  setUniversalRelevant( eq_terms[i] );\r
-                  assertEq = true;\r
-                }\r
-              }\r
-              if( assertEq ){\r
-                Node exp;\r
-                d_uequalityEngine.assertEquality( t.eqNode( eq_terms[i] ), true, exp );\r
-              }else{\r
-                Trace("thm-ee-no-add") << "Do not add : " << t << " == " << eq_terms[i] << std::endl;\r
-              }\r
-            }\r
-          }else{\r
-            Trace("thm-ee-add") << "UEE : No equivalent terms." << std::endl;\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if( d_uequalityEngine.hasTerm( n ) ){\r
-    Node r = d_uequalityEngine.getRepresentative( n );\r
-    EqcInfo * ei = getOrMakeEqcInfo( r );\r
-    if( ei && !ei->d_rep.get().isNull() ){\r
-      return ei->d_rep.get();\r
-    }else{\r
-      return r;\r
-    }\r
-  }else{\r
-    return n;\r
-  }\r
-}\r
-\r
-Node ConjectureGenerator::getFreeVar( TypeNode tn, unsigned i ) {\r
-  Assert( !tn.isNull() );\r
-  while( d_free_var[tn].size()<=i ){\r
-    std::stringstream oss;\r
-    oss << tn;\r
-    std::string typ_name = oss.str();\r
-    while( typ_name[0]=='(' ){\r
-      typ_name.erase( typ_name.begin() );\r
-    }\r
-    std::stringstream os;\r
-    os << typ_name[0] << i;\r
-    Node x = NodeManager::currentNM()->mkBoundVar( os.str().c_str(), tn );\r
-    d_free_var_num[x] = d_free_var[tn].size();\r
-    d_free_var[tn].push_back( x );\r
-  }\r
-  return d_free_var[tn][i];\r
-}\r
-\r
-\r
-\r
-Node ConjectureGenerator::getCanonicalTerm( TNode n, std::map< TypeNode, unsigned >& var_count, std::map< TNode, TNode >& subs ) {\r
-  if( n.getKind()==BOUND_VARIABLE ){\r
-    std::map< TNode, TNode >::iterator it = subs.find( n );\r
-    if( it==subs.end() ){\r
-      TypeNode tn = n.getType();\r
-      //allocate variable\r
-      unsigned vn = var_count[tn];\r
-      var_count[tn]++;\r
-      subs[n] = getFreeVar( tn, vn );\r
-      return subs[n];\r
-    }else{\r
-      return it->second;\r
-    }\r
-  }else{\r
-    std::vector< Node > children;\r
-    if( n.getKind()!=EQUAL ){\r
-      if( n.hasOperator() ){\r
-        TNode op = n.getOperator();\r
-        if( !d_tge.isRelevantFunc( op ) ){\r
-          return Node::null();\r
-        }\r
-        children.push_back( op );\r
-      }else{\r
-        return Node::null();\r
-      }\r
-    }\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      Node cn = getCanonicalTerm( n[i], var_count, subs );\r
-      if( cn.isNull() ){\r
-        return Node::null();\r
-      }else{\r
-        children.push_back( cn );\r
-      }\r
-    }\r
-    return NodeManager::currentNM()->mkNode( n.getKind(), children );\r
-  }\r
-}\r
-\r
-bool ConjectureGenerator::isHandledTerm( TNode n ){\r
-  return !n.getAttribute(NoMatchAttribute()) && inst::Trigger::isAtomicTrigger( n ) && ( n.getKind()!=APPLY_UF || n.getOperator().getKind()!=SKOLEM );\r
-}\r
-\r
-Node ConjectureGenerator::getGroundEqc( TNode r ) {\r
-  std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );\r
-  return it!=d_ground_eqc_map.end() ? it->second : Node::null();\r
-}\r
-\r
-bool ConjectureGenerator::isGroundEqc( TNode r ) {\r
-  return d_ground_eqc_map.find( r )!=d_ground_eqc_map.end();\r
-}\r
-\r
-bool ConjectureGenerator::isGroundTerm( TNode n ) {\r
-  return std::find( d_ground_terms.begin(), d_ground_terms.end(), n )!=d_ground_terms.end();\r
-}\r
-\r
-bool ConjectureGenerator::needsCheck( Theory::Effort e ) {\r
-  // synchonized with instantiation engine\r
-  return d_quantEngine->getInstWhenNeedsCheck( e );\r
-}\r
-\r
-bool ConjectureGenerator::hasEnumeratedUf( Node n ) {\r
-  if( options::conjectureGenGtEnum()>0 ){\r
-    std::map< Node, bool >::iterator it = d_uf_enum.find( n.getOperator() );\r
-    if( it==d_uf_enum.end() ){\r
-      d_uf_enum[n.getOperator()] = true;\r
-      std::vector< Node > lem;\r
-      getEnumeratePredUfTerm( n, options::conjectureGenGtEnum(), lem );\r
-      if( !lem.empty() ){\r
-        for( unsigned j=0; j<lem.size(); j++ ){\r
-          d_quantEngine->addLemma( lem[j], false );\r
-          d_hasAddedLemma = true;\r
-        }\r
-        return false;\r
-      }\r
-    }\r
-  }\r
-  return true;\r
-}\r
-\r
-void ConjectureGenerator::reset_round( Theory::Effort e ) {\r
-\r
-}\r
-\r
-void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {\r
-  if( quant_e==QuantifiersEngine::QEFFORT_STANDARD ){\r
-    d_fullEffortCount++;\r
-    if( d_fullEffortCount%optFullCheckFrequency()==0 ){\r
-      d_hasAddedLemma = false;\r
-      d_tge.d_cg = this;\r
-      double clSet = 0;\r
-      if( Trace.isOn("sg-engine") ){\r
-        clSet = double(clock())/double(CLOCKS_PER_SEC);\r
-        Trace("sg-engine") << "---Conjecture Engine Round, effort = " << e << "---" << std::endl;\r
-      }\r
-      eq::EqualityEngine * ee = getEqualityEngine();\r
-      d_conj_count = 0;\r
-\r
-      Trace("sg-proc") << "Get eq classes..." << std::endl;\r
-      d_op_arg_index.clear();\r
-      d_ground_eqc_map.clear();\r
-      d_bool_eqc[0] = Node::null();\r
-      d_bool_eqc[1] = Node::null();\r
-      std::vector< TNode > eqcs;\r
-      d_em.clear();\r
-      eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( ee );\r
-      while( !eqcs_i.isFinished() ){\r
-        TNode r = (*eqcs_i);\r
-        eqcs.push_back( r );\r
-        if( r.getType().isBoolean() ){\r
-          if( areEqual( r, getTermDatabase()->d_true ) ){\r
-            d_ground_eqc_map[r] = getTermDatabase()->d_true;\r
-            d_bool_eqc[0] = r;\r
-          }else if( areEqual( r, getTermDatabase()->d_false ) ){\r
-            d_ground_eqc_map[r] = getTermDatabase()->d_false;\r
-            d_bool_eqc[1] = r;\r
-          }\r
-        }\r
-        d_em[r] = eqcs.size();\r
-        eq::EqClassIterator ieqc_i = eq::EqClassIterator( r, ee );\r
-        while( !ieqc_i.isFinished() ){\r
-          TNode n = (*ieqc_i);\r
-          if( getTermDatabase()->hasTermCurrent( n ) ){\r
-            if( isHandledTerm( n ) ){\r
-              d_op_arg_index[r].addTerm( this, n );\r
-            }\r
-          }\r
-          ++ieqc_i;\r
-        }\r
-        ++eqcs_i;\r
-      }\r
-      Assert( !d_bool_eqc[0].isNull() );\r
-      Assert( !d_bool_eqc[1].isNull() );\r
-      d_urelevant_terms.clear();\r
-      Trace("sg-proc") << "...done get eq classes" << std::endl;\r
-\r
-      Trace("sg-proc") << "Determine ground EQC..." << std::endl;\r
-      bool success;\r
-      do{\r
-        success = false;\r
-        for( unsigned i=0; i<eqcs.size(); i++ ){\r
-          TNode r = eqcs[i];\r
-          if( d_ground_eqc_map.find( r )==d_ground_eqc_map.end() ){\r
-            std::vector< TNode > args;\r
-            Trace("sg-pat-debug") << "******* Get ground term for " << r << std::endl;\r
-            Node n;\r
-            if( getTermDatabase()->isInductionTerm( r ) ){\r
-              n = d_op_arg_index[r].getGroundTerm( this, args );\r
-            }else{\r
-              n = r;\r
-            }\r
-            if( !n.isNull() ){\r
-              Trace("sg-pat") << "Ground term for eqc " << r << " : " << std::endl;\r
-              Trace("sg-pat") << "   " << n << std::endl;\r
-              d_ground_eqc_map[r] = n;\r
-              success = true;\r
-            }else{\r
-              Trace("sg-pat-debug") << "...could not find ground term." << std::endl;\r
-            }\r
-          }\r
-        }\r
-      }while( success );\r
-      //also get ground terms\r
-      d_ground_terms.clear();\r
-      for( unsigned i=0; i<eqcs.size(); i++ ){\r
-        TNode r = eqcs[i];\r
-        d_op_arg_index[r].getGroundTerms( this, d_ground_terms );\r
-      }\r
-      Trace("sg-proc") << "...done determine ground EQC" << std::endl;\r
-\r
-      //debug printing\r
-      if( Trace.isOn("sg-gen-eqc") ){\r
-        for( unsigned i=0; i<eqcs.size(); i++ ){\r
-          TNode r = eqcs[i];\r
-          //print out members\r
-          bool firstTime = true;\r
-          bool isFalse = areEqual( r, getTermDatabase()->d_false );\r
-          eq::EqClassIterator eqc_i = eq::EqClassIterator( r, ee );\r
-          while( !eqc_i.isFinished() ){\r
-            TNode n = (*eqc_i);\r
-            if( getTermDatabase()->hasTermCurrent( n ) && !n.getAttribute(NoMatchAttribute()) && ( n.getKind()!=EQUAL || isFalse ) ){\r
-              if( firstTime ){\r
-                Trace("sg-gen-eqc") << "e" << d_em[r] << " : { " << std::endl;\r
-                firstTime = false;\r
-              }\r
-              if( n.hasOperator() ){\r
-                Trace("sg-gen-eqc") << "   (" << n.getOperator();\r
-                getTermDatabase()->computeArgReps( n );\r
-                for( unsigned i=0; i<getTermDatabase()->d_arg_reps[n].size(); i++ ){\r
-                  Trace("sg-gen-eqc") << " e" << d_em[getTermDatabase()->d_arg_reps[n][i]];\r
-                }\r
-                Trace("sg-gen-eqc") << ") :: " << n << std::endl;\r
-              }else{\r
-                Trace("sg-gen-eqc") << "   " << n << std::endl;\r
-              }\r
-            }\r
-            ++eqc_i;\r
-          }\r
-          if( !firstTime ){\r
-            Trace("sg-gen-eqc") << "}" << std::endl;\r
-            //print out ground term\r
-            std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );\r
-            if( it!=d_ground_eqc_map.end() ){\r
-              Trace("sg-gen-eqc") << "- Ground term : " << it->second << std::endl;\r
-            }\r
-          }\r
-        }\r
-      }\r
-\r
-      Trace("sg-proc") << "Compute relevant eqc..." << std::endl;\r
-      d_tge.d_relevant_eqc[0].clear();\r
-      d_tge.d_relevant_eqc[1].clear();\r
-      for( unsigned i=0; i<eqcs.size(); i++ ){\r
-        TNode r = eqcs[i];\r
-        std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );\r
-        unsigned index = 1;\r
-        if( it==d_ground_eqc_map.end() ){\r
-          index = 0;\r
-        }\r
-        //based on unproven conjectures? TODO\r
-        d_tge.d_relevant_eqc[index].push_back( r );\r
-      }\r
-      Trace("sg-gen-tg-debug") << "Initial relevant eqc : ";\r
-      for( unsigned i=0; i<d_tge.d_relevant_eqc[0].size(); i++ ){\r
-        Trace("sg-gen-tg-debug") << "e" << d_em[d_tge.d_relevant_eqc[0][i]] << " ";\r
-      }\r
-      Trace("sg-gen-tg-debug") << std::endl;\r
-      Trace("sg-proc") << "...done compute relevant eqc" << std::endl;\r
-\r
-\r
-      Trace("sg-proc") << "Collect signature information..." << std::endl;\r
-      d_tge.collectSignatureInformation();\r
-      if( d_hasAddedLemma ){\r
-        Trace("sg-proc") << "...added enumeration lemmas." << std::endl;\r
-      }\r
-      Trace("sg-proc") << "...done collect signature information" << std::endl;\r
-\r
-\r
-\r
-      Trace("sg-proc") << "Build theorem index..." << std::endl;\r
-      d_ue_canon.clear();\r
-      d_thm_index.clear();\r
-      std::vector< Node > provenConj;\r
-      quantifiers::FirstOrderModel* m = d_quantEngine->getModel();\r
-      for( int i=0; i<m->getNumAssertedQuantifiers(); i++ ){\r
-        Node q = m->getAssertedQuantifier( i );\r
-        Trace("thm-db-debug") << "Is " << q << " a relevant theorem?" << std::endl;\r
-        Node conjEq;\r
-        if( q[1].getKind()==EQUAL ){\r
-          bool isSubsume = false;\r
-          bool inEe = false;\r
-          for( unsigned r=0; r<2; r++ ){\r
-            TNode nl = q[1][r==0 ? 0 : 1];\r
-            TNode nr = q[1][r==0 ? 1 : 0];\r
-            Node eq = nl.eqNode( nr );\r
-            if( r==1 || std::find( d_conjectures.begin(), d_conjectures.end(), q )==d_conjectures.end() ){\r
-              //must make it canonical\r
-              std::map< TypeNode, unsigned > var_count;\r
-              std::map< TNode, TNode > subs;\r
-              Trace("sg-proc-debug") << "get canonical " << eq << std::endl;\r
-              eq = getCanonicalTerm( eq, var_count, subs );\r
-            }\r
-            if( !eq.isNull() ){\r
-              if( r==0 ){\r
-                inEe = d_ee_conjectures.find( q[1] )!=d_ee_conjectures.end();\r
-                if( !inEe ){\r
-                  //add to universal equality engine\r
-                  Node nl = getUniversalRepresentative( eq[0], true );\r
-                  Node nr = getUniversalRepresentative( eq[1], true );\r
-                  if( areUniversalEqual( nl, nr ) ){\r
-                    isSubsume = true;\r
-                    //set inactive (will be ignored by other modules)\r
-                    d_quantEngine->getModel()->setQuantifierActive( q, false );\r
-                  }else{\r
-                    Node exp;\r
-                    d_ee_conjectures[q[1]] = true;\r
-                    d_uequalityEngine.assertEquality( nl.eqNode( nr ), true, exp );\r
-                  }\r
-                }\r
-                Trace("sg-conjecture") << "*** CONJECTURE : currently proven" << (isSubsume ? " and subsumed" : "");\r
-                Trace("sg-conjecture") << " : " << q[1] << std::endl;\r
-                provenConj.push_back( q );\r
-              }\r
-              if( !isSubsume ){\r
-                Trace("thm-db-debug") << "Adding theorem to database " << eq[0] << " == " << eq[1] << std::endl;\r
-                d_thm_index.addTheorem( eq[0], eq[1] );\r
-              }else{\r
-                break;\r
-              }\r
-            }else{\r
-              break;\r
-            }\r
-          }\r
-        }\r
-      }\r
-      //examine status of other conjectures\r
-      for( unsigned i=0; i<d_conjectures.size(); i++ ){\r
-        Node q = d_conjectures[i];\r
-        if( std::find( provenConj.begin(), provenConj.end(), q )==provenConj.end() ){\r
-          //check each skolem variable\r
-          bool disproven = true;\r
-          //std::vector< Node > sk;\r
-          //getTermDatabase()->getSkolemConstants( q, sk, true );\r
-          Trace("sg-conjecture") << "    CONJECTURE : ";\r
-          std::vector< Node > ce;\r
-          for( unsigned j=0; j<getTermDatabase()->d_skolem_constants[q].size(); j++ ){\r
-            TNode k = getTermDatabase()->d_skolem_constants[q][j];\r
-            TNode rk = getRepresentative( k );\r
-            std::map< TNode, Node >::iterator git = d_ground_eqc_map.find( rk );\r
-            //check if it is a ground term\r
-            if( git==d_ground_eqc_map.end() ){\r
-              Trace("sg-conjecture") << "ACTIVE : " << q;\r
-              if( Trace.isOn("sg-gen-eqc") ){\r
-                Trace("sg-conjecture") << " { ";\r
-                for( unsigned k=0; k<getTermDatabase()->d_skolem_constants[q].size(); k++ ){ Trace("sg-conjecture") << getTermDatabase()->d_skolem_constants[q][k] << ( j==k ? "*" : "" ) << " "; }\r
-                Trace("sg-conjecture") << "}";\r
-              }\r
-              Trace("sg-conjecture") << std::endl;\r
-              disproven = false;\r
-              break;\r
-            }else{\r
-              ce.push_back( git->second );\r
-            }\r
-          }\r
-          if( disproven ){\r
-            Trace("sg-conjecture") << "disproven : " << q << " : ";\r
-            for( unsigned i=0; i<ce.size(); i++ ){\r
-              Trace("sg-conjecture") << q[0][i] << " -> " << ce[i] << " ";\r
-            }\r
-            Trace("sg-conjecture") << std::endl;\r
-          }\r
-        }\r
-      }\r
-      Trace("thm-db") << "Theorem database is : " << std::endl;\r
-      d_thm_index.debugPrint( "thm-db" );\r
-      Trace("thm-db") << std::endl;\r
-      Trace("sg-proc") << "...done build theorem index" << std::endl;\r
-\r
-\r
-      //clear patterns\r
-      d_patterns.clear();\r
-      d_pattern_var_id.clear();\r
-      d_pattern_var_duplicate.clear();\r
-      d_pattern_is_normal.clear();\r
-      d_pattern_is_relevant.clear();\r
-      d_pattern_fun_id.clear();\r
-      d_pattern_fun_sum.clear();\r
-      d_rel_patterns.clear();\r
-      d_rel_pattern_var_sum.clear();\r
-      d_rel_pattern_typ_index.clear();\r
-      d_rel_pattern_subs_index.clear();\r
-\r
-      unsigned rel_term_count = 0;\r
-      std::map< TypeNode, unsigned > rt_var_max;\r
-      std::vector< TypeNode > rt_types;\r
-      std::map< TypeNode, std::map< int, std::vector< Node > > > conj_lhs;\r
-      unsigned addedLemmas = 0;\r
-      for( unsigned depth=1; depth<=3; depth++ ){\r
-        Trace("sg-proc") << "Generate relevant LHS at depth " << depth << "..." << std::endl;\r
-        Trace("sg-rel-term") << "Relevant terms of depth " << depth << " : " << std::endl;\r
-        //set up environment\r
-        d_tge.d_var_id.clear();\r
-        d_tge.d_var_limit.clear();\r
-        d_tge.reset( depth, true, TypeNode::null() );\r
-        while( d_tge.getNextTerm() ){\r
-          //construct term\r
-          Node nn = d_tge.getTerm();\r
-          if( !options::conjectureFilterCanonical() || considerTermCanon( nn, true ) ){\r
-            rel_term_count++;\r
-            Trace("sg-rel-term") << "*** Relevant term : ";\r
-            d_tge.debugPrint( "sg-rel-term", "sg-rel-term-debug2" );\r
-            Trace("sg-rel-term") << std::endl;\r
-\r
-            for( unsigned r=0; r<2; r++ ){\r
-              Trace("sg-rel-term-debug") << "...from equivalence classes (" << r << ") : ";\r
-              int index = d_tge.d_ccand_eqc[r].size()-1;\r
-              for( unsigned j=0; j<d_tge.d_ccand_eqc[r][index].size(); j++ ){\r
-                Trace("sg-rel-term-debug") << "e" << d_em[d_tge.d_ccand_eqc[r][index][j]] << " ";\r
-              }\r
-              Trace("sg-rel-term-debug") << std::endl;\r
-            }\r
-            TypeNode tnn = nn.getType();\r
-            Trace("sg-gen-tg-debug") << "...term is " << nn << std::endl;\r
-            conj_lhs[tnn][depth].push_back( nn );\r
-\r
-            //add information about pattern\r
-            Trace("sg-gen-tg-debug") << "Collect pattern information..." << std::endl;\r
-            Assert( std::find( d_rel_patterns[tnn].begin(), d_rel_patterns[tnn].end(), nn )==d_rel_patterns[tnn].end() );\r
-            d_rel_patterns[tnn].push_back( nn );\r
-            //build information concerning the variables in this pattern\r
-            unsigned sum = 0;\r
-            std::map< TypeNode, unsigned > typ_to_subs_index;\r
-            std::vector< TNode > gsubs_vars;\r
-            for( std::map< TypeNode, unsigned >::iterator it = d_tge.d_var_id.begin(); it != d_tge.d_var_id.end(); ++it ){\r
-              if( it->second>0 ){\r
-                typ_to_subs_index[it->first] = sum;\r
-                sum += it->second;\r
-                for( unsigned i=0; i<it->second; i++ ){\r
-                  gsubs_vars.push_back( getFreeVar( it->first, i ) );\r
-                }\r
-              }\r
-            }\r
-            d_rel_pattern_var_sum[nn] = sum;\r
-            //register the pattern\r
-            registerPattern( nn, tnn );\r
-            Assert( d_pattern_is_normal[nn] );\r
-            Trace("sg-gen-tg-debug") << "...done collect pattern information" << std::endl;\r
-\r
-            //record information about types\r
-            Trace("sg-gen-tg-debug") << "Collect type information..." << std::endl;\r
-            PatternTypIndex * pti = &d_rel_pattern_typ_index;\r
-            for( std::map< TypeNode, unsigned >::iterator it = d_tge.d_var_id.begin(); it != d_tge.d_var_id.end(); ++it ){\r
-              pti = &pti->d_children[it->first][it->second];\r
-              //record maximum\r
-              if( rt_var_max.find( it->first )==rt_var_max.end() || it->second>rt_var_max[it->first] ){\r
-                rt_var_max[it->first] = it->second;\r
-              }\r
-            }\r
-            if( std::find( rt_types.begin(), rt_types.end(), tnn )==rt_types.end() ){\r
-              rt_types.push_back( tnn );\r
-            }\r
-            pti->d_terms.push_back( nn );\r
-            Trace("sg-gen-tg-debug") << "...done collect type information" << std::endl;\r
-\r
-            Trace("sg-gen-tg-debug") << "Build substitutions for ground EQC..." << std::endl;\r
-            std::vector< TNode > gsubs_terms;\r
-            gsubs_terms.resize( gsubs_vars.size() );\r
-            int index = d_tge.d_ccand_eqc[1].size()-1;\r
-            for( unsigned j=0; j<d_tge.d_ccand_eqc[1][index].size(); j++ ){\r
-              TNode r = d_tge.d_ccand_eqc[1][index][j];\r
-              Trace("sg-rel-term-debug") << "  Matches for e" << d_em[r] << ", which is ground term " << d_ground_eqc_map[r] << ":" << std::endl;\r
-              std::map< TypeNode, std::map< unsigned, TNode > > subs;\r
-              std::map< TNode, bool > rev_subs;\r
-              //only get ground terms\r
-              unsigned mode = 2;\r
-              d_tge.resetMatching( r, mode );\r
-              while( d_tge.getNextMatch( r, subs, rev_subs ) ){\r
-                //we will be building substitutions\r
-                bool firstTime = true;\r
-                for( std::map< TypeNode, std::map< unsigned, TNode > >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
-                  unsigned tindex = typ_to_subs_index[it->first];\r
-                  for( std::map< unsigned, TNode >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){\r
-                    if( !firstTime ){\r
-                      Trace("sg-rel-term-debug") << ", ";\r
-                    }else{\r
-                      firstTime = false;\r
-                      Trace("sg-rel-term-debug") << "    ";\r
-                    }\r
-                    Trace("sg-rel-term-debug") << it->first << ":x" << it2->first << " -> " << it2->second;\r
-                    Assert( tindex+it2->first<gsubs_terms.size() );\r
-                    gsubs_terms[tindex+it2->first] = it2->second;\r
-                  }\r
-                }\r
-                Trace("sg-rel-term-debug") << std::endl;\r
-                d_rel_pattern_subs_index[nn].addSubstitution( r, gsubs_vars, gsubs_terms );\r
-              }\r
-            }\r
-            Trace("sg-gen-tg-debug") << "...done build substitutions for ground EQC" << std::endl;\r
-          }else{\r
-            Trace("sg-gen-tg-debug") << "> not canonical : " << nn << std::endl;\r
-          }\r
-        }\r
-        Trace("sg-proc") << "...done generate terms at depth " << depth << std::endl;\r
-        Trace("sg-stats") << "--------> Total LHS of depth " << depth << " : " << rel_term_count << std::endl;\r
-        //Trace("conjecture-count") << "Total LHS of depth " << depth << " : " << conj_lhs[depth].size() << std::endl;\r
-\r
-        /* test...\r
-        for( unsigned i=0; i<rt_types.size(); i++ ){\r
-          Trace("sg-term-enum") << "Term enumeration for " << rt_types[i] << " : " << std::endl;\r
-          Trace("sg-term-enum") << "Ground term : " << rt_types[i].mkGroundTerm() << std::endl;\r
-          for( unsigned j=0; j<150; j++ ){\r
-            Trace("sg-term-enum") << "  " << getEnumerateTerm( rt_types[i], j ) << std::endl;\r
-          }\r
-        }\r
-        */\r
-\r
-        //consider types from relevant terms\r
-        for( unsigned rdepth=0; rdepth<=depth; rdepth++ ){\r
-          //set up environment\r
-          d_tge.d_var_id.clear();\r
-          d_tge.d_var_limit.clear();\r
-          for( std::map< TypeNode, unsigned >::iterator it = rt_var_max.begin(); it != rt_var_max.end(); ++it ){\r
-            d_tge.d_var_id[ it->first ] = it->second;\r
-            d_tge.d_var_limit[ it->first ] = it->second;\r
-          }\r
-          std::random_shuffle( rt_types.begin(), rt_types.end() );\r
-          std::map< TypeNode, std::vector< Node > > conj_rhs;\r
-          for( unsigned i=0; i<rt_types.size(); i++ ){\r
-\r
-            Trace("sg-proc") << "Generate relevant RHS terms of type " << rt_types[i] << " at depth " << rdepth << "..." << std::endl;\r
-            d_tge.reset( rdepth, false, rt_types[i] );\r
-\r
-            while( d_tge.getNextTerm() ){\r
-              Node rhs = d_tge.getTerm();\r
-              if( considerTermCanon( rhs, false ) ){\r
-                Trace("sg-rel-prop") << "Relevant RHS : " << rhs << std::endl;\r
-                //register pattern\r
-                Assert( rhs.getType()==rt_types[i] );\r
-                registerPattern( rhs, rt_types[i] );\r
-                if( rdepth<depth ){\r
-                  //consider against all LHS at depth\r
-                  for( unsigned j=0; j<conj_lhs[rt_types[i]][depth].size(); j++ ){\r
-                    processCandidateConjecture( conj_lhs[rt_types[i]][depth][j], rhs, depth, rdepth );\r
-                  }\r
-                }else{\r
-                  conj_rhs[rt_types[i]].push_back( rhs );\r
-                }\r
-              }\r
-            }\r
-          }\r
-          flushWaitingConjectures( addedLemmas, depth, rdepth );\r
-          //consider against all LHS up to depth\r
-          if( rdepth==depth ){\r
-            for( unsigned lhs_depth = 1; lhs_depth<=depth; lhs_depth++ ){\r
-              if( (int)addedLemmas<options::conjectureGenPerRound() ){\r
-                Trace("sg-proc") << "Consider conjectures at depth (" << lhs_depth << ", " << rdepth << ")..." << std::endl;\r
-                for( std::map< TypeNode, std::vector< Node > >::iterator it = conj_rhs.begin(); it != conj_rhs.end(); ++it ){\r
-                  for( unsigned j=0; j<it->second.size(); j++ ){\r
-                    for( unsigned k=0; k<conj_lhs[it->first][lhs_depth].size(); k++ ){\r
-                      processCandidateConjecture( conj_lhs[it->first][lhs_depth][k], it->second[j], lhs_depth, rdepth );\r
-                    }\r
-                  }\r
-                }\r
-                flushWaitingConjectures( addedLemmas, lhs_depth, depth );\r
-              }\r
-            }\r
-          }\r
-          if( (int)addedLemmas>=options::conjectureGenPerRound() ){\r
-            break;\r
-          }\r
-        }\r
-        if( (int)addedLemmas>=options::conjectureGenPerRound() ){\r
-          break;\r
-        }\r
-      }\r
-      Trace("sg-stats") << "Total conjectures considered : " << d_conj_count << std::endl;\r
-      if( Trace.isOn("thm-ee") ){\r
-        Trace("thm-ee") << "Universal equality engine is : " << std::endl;\r
-        eq::EqClassesIterator ueqcs_i = eq::EqClassesIterator( &d_uequalityEngine );\r
-        while( !ueqcs_i.isFinished() ){\r
-          TNode r = (*ueqcs_i);\r
-          bool firstTime = true;\r
-          TNode rr = getUniversalRepresentative( r );\r
-          Trace("thm-ee") << "  " << rr;\r
-          Trace("thm-ee") << " : { ";\r
-          eq::EqClassIterator ueqc_i = eq::EqClassIterator( r, &d_uequalityEngine );\r
-          while( !ueqc_i.isFinished() ){\r
-            TNode n = (*ueqc_i);\r
-            if( rr!=n ){\r
-              if( firstTime ){\r
-                Trace("thm-ee") << std::endl;\r
-                firstTime = false;\r
-              }\r
-              Trace("thm-ee") << "    " << n << std::endl;\r
-            }\r
-            ++ueqc_i;\r
-          }\r
-          if( !firstTime ){ Trace("thm-ee") << "  "; }\r
-          Trace("thm-ee") << "}" << std::endl;\r
-          ++ueqcs_i;\r
-        }\r
-        Trace("thm-ee") << std::endl;\r
-      }\r
-      if( Trace.isOn("sg-engine") ){\r
-        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);\r
-        Trace("sg-engine") << "Finished conjecture generator, time = " << (clSet2-clSet) << std::endl;\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-unsigned ConjectureGenerator::flushWaitingConjectures( unsigned& addedLemmas, int ldepth, int rdepth ) {\r
-  if( !d_waiting_conjectures_lhs.empty() ){\r
-    Trace("sg-proc") << "Generated " << d_waiting_conjectures_lhs.size() << " conjectures at depth " << ldepth << "/" << rdepth << "." << std::endl;\r
-    if( (int)addedLemmas<options::conjectureGenPerRound() ){\r
-      /*\r
-      std::vector< unsigned > indices;\r
-      for( unsigned i=0; i<d_waiting_conjectures_lhs.size(); i++ ){\r
-        indices.push_back( i );\r
-      }\r
-      bool doSort = false;\r
-      if( doSort ){\r
-        //sort them based on score\r
-        sortConjectureScore scs;\r
-        scs.d_scores.insert( scs.d_scores.begin(), d_waiting_conjectures_score.begin(), d_waiting_conjectures_score.end() );\r
-        std::sort( indices.begin(), indices.end(), scs );\r
-      }\r
-      //if( doSort && d_waiting_conjectures_score[indices[0]]<optFilterScoreThreshold() ){\r
-      */\r
-      unsigned prevCount = d_conj_count;\r
-      for( unsigned i=0; i<d_waiting_conjectures_lhs.size(); i++ ){\r
-        if( d_waiting_conjectures_score[i]>=optFilterScoreThreshold() ){\r
-          //we have determined a relevant subgoal\r
-          Node lhs = d_waiting_conjectures_lhs[i];\r
-          Node rhs = d_waiting_conjectures_rhs[i];\r
-          if( options::conjectureFilterCanonical() && ( getUniversalRepresentative( lhs )!=lhs || getUniversalRepresentative( rhs )!=rhs ) ){\r
-            //skip\r
-          }else{\r
-            Trace("sg-engine") << "*** Consider conjecture : " << lhs << " == " << rhs << std::endl;\r
-            Trace("sg-engine-debug") << "      score : " << d_waiting_conjectures_score[i] << std::endl;\r
-            if( optStatsOnly() ){\r
-              d_conj_count++;\r
-            }else{\r
-              std::vector< Node > bvs;\r
-              for( std::map< TypeNode, unsigned >::iterator it = d_pattern_var_id[lhs].begin(); it != d_pattern_var_id[lhs].end(); ++it ){\r
-                for( unsigned i=0; i<=it->second; i++ ){\r
-                  bvs.push_back( getFreeVar( it->first, i ) );\r
-                }\r
-              }\r
-              Node rsg;\r
-              if( !bvs.empty() ){\r
-                Node bvl = NodeManager::currentNM()->mkNode( BOUND_VAR_LIST, bvs );\r
-                rsg = NodeManager::currentNM()->mkNode( FORALL, bvl, lhs.eqNode( rhs ) );\r
-              }else{\r
-                rsg = lhs.eqNode( rhs );\r
-              }\r
-              rsg = Rewriter::rewrite( rsg );\r
-              d_conjectures.push_back( rsg );\r
-              d_eq_conjectures[lhs].push_back( rhs );\r
-              d_eq_conjectures[rhs].push_back( lhs );\r
-\r
-              Node lem = NodeManager::currentNM()->mkNode( OR, rsg.negate(), rsg );\r
-              d_quantEngine->addLemma( lem, false );\r
-              d_quantEngine->addRequirePhase( rsg, false );\r
-              addedLemmas++;\r
-              if( (int)addedLemmas>=options::conjectureGenPerRound() ){\r
-                break;\r
-              }\r
-            }\r
-          }\r
-        }\r
-      }\r
-      Trace("sg-proc") << "...have now added " << addedLemmas << " conjecture lemmas." << std::endl;\r
-      if( optStatsOnly() ){\r
-        Trace("sg-stats") << "Generated " << (d_conj_count-prevCount) << " conjectures at depth " << ldepth << "/" << rdepth << "." << std::endl;\r
-      }\r
-    }\r
-    d_waiting_conjectures_lhs.clear();\r
-    d_waiting_conjectures_rhs.clear();\r
-    d_waiting_conjectures_score.clear();\r
-    d_waiting_conjectures.clear();\r
-  }\r
-  return addedLemmas;\r
-}\r
-\r
-void ConjectureGenerator::registerQuantifier( Node q ) {\r
-\r
-}\r
-\r
-void ConjectureGenerator::assertNode( Node n ) {\r
-\r
-}\r
-\r
-bool ConjectureGenerator::considerTermCanon( Node ln, bool genRelevant ){\r
-  if( !ln.isNull() ){\r
-    //do not consider if it is non-canonical, and either:\r
-    //  (1) we are not generating relevant terms, or\r
-    //  (2) its canonical form is a generalization.\r
-    TNode lnr = getUniversalRepresentative( ln, true );\r
-    if( lnr==ln ){\r
-      markReportedCanon( ln );\r
-    }else if( !genRelevant || isGeneralization( lnr, ln ) ){\r
-      Trace("sg-gen-consider-term") << "Do not consider term, " << ln << " is not canonical representation (which is " << lnr << ")." << std::endl;\r
-      return false;\r
-    }\r
-  }\r
-  Trace("sg-gen-tg-debug") << "Will consider term canon " << ln << std::endl;\r
-  Trace("sg-gen-consider-term-debug") << std::endl;\r
-  return true;\r
-}\r
-\r
-unsigned ConjectureGenerator::collectFunctions( TNode opat, TNode pat, std::map< TNode, unsigned >& funcs,\r
-                                             std::map< TypeNode, unsigned >& mnvn, std::map< TypeNode, unsigned >& mxvn ){\r
-  if( pat.hasOperator() ){\r
-    funcs[pat.getOperator()]++;\r
-    if( !d_tge.isRelevantFunc( pat.getOperator() ) ){\r
-      d_pattern_is_relevant[opat] = false;\r
-    }\r
-    unsigned sum = 1;\r
-    for( unsigned i=0; i<pat.getNumChildren(); i++ ){\r
-      sum += collectFunctions( opat, pat[i], funcs, mnvn, mxvn );\r
-    }\r
-    return sum;\r
-  }else{\r
-    Assert( pat.getNumChildren()==0 );\r
-    funcs[pat]++;\r
-    //for variables\r
-    if( pat.getKind()==BOUND_VARIABLE ){\r
-      if( funcs[pat]>1 ){\r
-        //duplicate variable\r
-        d_pattern_var_duplicate[opat]++;\r
-      }else{\r
-        //check for max/min\r
-        TypeNode tn = pat.getType();\r
-        unsigned vn = d_free_var_num[pat];\r
-        std::map< TypeNode, unsigned >::iterator it = mnvn.find( tn );\r
-        if( it!=mnvn.end() ){\r
-          if( vn<it->second ){\r
-            d_pattern_is_normal[opat] = false;\r
-            mnvn[tn] = vn;\r
-          }else if( vn>mxvn[tn] ){\r
-            if( vn!=mxvn[tn]+1 ){\r
-              d_pattern_is_normal[opat] = false;\r
-            }\r
-            mxvn[tn] = vn;\r
-          }\r
-        }else{\r
-          //first variable of this type\r
-          mnvn[tn] = vn;\r
-          mxvn[tn] = vn;\r
-        }\r
-      }\r
-    }else{\r
-      d_pattern_is_relevant[opat] = false;\r
-    }\r
-    return 1;\r
-  }\r
-}\r
-\r
-void ConjectureGenerator::registerPattern( Node pat, TypeNode tpat ) {\r
-  if( std::find( d_patterns[tpat].begin(), d_patterns[tpat].end(), pat )==d_patterns[tpat].end() ){\r
-    d_patterns[TypeNode::null()].push_back( pat );\r
-    d_patterns[tpat].push_back( pat );\r
-\r
-    Assert( d_pattern_fun_id.find( pat )==d_pattern_fun_id.end() );\r
-    Assert( d_pattern_var_id.find( pat )==d_pattern_var_id.end() );\r
-\r
-    //collect functions\r
-    std::map< TypeNode, unsigned > mnvn;\r
-    d_pattern_fun_sum[pat] = collectFunctions( pat, pat, d_pattern_fun_id[pat], mnvn, d_pattern_var_id[pat] );\r
-    if( d_pattern_is_normal.find( pat )==d_pattern_is_normal.end() ){\r
-      d_pattern_is_normal[pat] = true;\r
-    }\r
-    if( d_pattern_is_relevant.find( pat )==d_pattern_is_relevant.end() ){\r
-      d_pattern_is_relevant[pat] = true;\r
-    }\r
-  }\r
-}\r
-\r
-bool ConjectureGenerator::isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs ) {\r
-  if( patg.getKind()==BOUND_VARIABLE ){\r
-    std::map< TNode, TNode >::iterator it = subs.find( patg );\r
-    if( it!=subs.end() ){\r
-      return it->second==pat;\r
-    }else{\r
-      subs[patg] = pat;\r
-      return true;\r
-    }\r
-  }else{\r
-    Assert( patg.hasOperator() );\r
-    if( !pat.hasOperator() || patg.getOperator()!=pat.getOperator() ){\r
-      return false;\r
-    }else{\r
-      Assert( patg.getNumChildren()==pat.getNumChildren() );\r
-      for( unsigned i=0; i<patg.getNumChildren(); i++ ){\r
-        if( !isGeneralization( patg[i], pat[i], subs ) ){\r
-          return false;\r
-        }\r
-      }\r
-      return true;\r
-    }\r
-  }\r
-}\r
-\r
-int ConjectureGenerator::calculateGeneralizationDepth( TNode n, std::vector< TNode >& fv ) {\r
-  if( n.getKind()==BOUND_VARIABLE ){\r
-    if( std::find( fv.begin(), fv.end(), n )==fv.end() ){\r
-      fv.push_back( n );\r
-      return 0;\r
-    }else{\r
-      return 1;\r
-    }\r
-  }else{\r
-    int depth = 1;\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      depth += calculateGeneralizationDepth( n[i], fv );\r
-    }\r
-    return depth;\r
-  }\r
-}\r
-\r
-Node ConjectureGenerator::getPredicateForType( TypeNode tn ) {\r
-  std::map< TypeNode, Node >::iterator it = d_typ_pred.find( tn );\r
-  if( it==d_typ_pred.end() ){\r
-    TypeNode op_tn = NodeManager::currentNM()->mkFunctionType( tn, NodeManager::currentNM()->booleanType() );\r
-    Node op = NodeManager::currentNM()->mkSkolem( "PE", op_tn, "was created by conjecture ground term enumerator." );\r
-    d_typ_pred[tn] = op;\r
-    return op;\r
-  }else{\r
-    return it->second;\r
-  }\r
-}\r
-\r
-void ConjectureGenerator::getEnumerateUfTerm( Node n, unsigned num, std::vector< Node >& terms ) {\r
-  if( n.getNumChildren()>0 ){\r
-    std::vector< int > vec;\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      vec.push_back( 0 );\r
-    }\r
-    vec.pop_back();\r
-    int size_limit = 0;\r
-    int vec_sum = -1;\r
-    unsigned index = 0;\r
-    unsigned last_size = terms.size();\r
-    while( terms.size()<num ){\r
-      bool success = true;\r
-      if( vec_sum==-1 ){\r
-        vec_sum = 0;\r
-        vec.push_back( size_limit );\r
-      }else{\r
-        //see if we can iterate current\r
-        if( vec_sum<size_limit && !getTermDatabase()->getEnumerateTerm( n[index].getType(), vec[index]+1 ).isNull() ){\r
-          vec[index]++;\r
-          vec_sum++;\r
-          vec.push_back( size_limit - vec_sum );\r
-        }else{\r
-          vec_sum -= vec[index];\r
-          vec[index] = 0;\r
-          index++;\r
-          if( index==n.getNumChildren() ){\r
-            success = false;\r
-          }\r
-        }\r
-      }\r
-      if( success ){\r
-        if( vec.size()==n.getNumChildren() ){\r
-          Node lc = getTermDatabase()->getEnumerateTerm( n[vec.size()-1].getType(), vec[vec.size()-1] );\r
-          if( !lc.isNull() ){\r
-            for( unsigned i=0; i<vec.size(); i++ ){\r
-              Trace("sg-gt-enum-debug") << vec[i] << " ";\r
-            }\r
-            Trace("sg-gt-enum-debug") << " / " << size_limit << std::endl;\r
-            for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-              Trace("sg-gt-enum-debug") << n[i].getType() << " ";\r
-            }\r
-            Trace("sg-gt-enum-debug") << std::endl;\r
-            std::vector< Node > children;\r
-            children.push_back( n.getOperator() );\r
-            for( unsigned i=0; i<(vec.size()-1); i++ ){\r
-              Node nn = getTermDatabase()->getEnumerateTerm( n[i].getType(), vec[i] );\r
-              Assert( !nn.isNull() );\r
-              Assert( nn.getType()==n[i].getType() );\r
-              children.push_back( nn );\r
-            }\r
-            children.push_back( lc );\r
-            Node n = NodeManager::currentNM()->mkNode( APPLY_UF, children );\r
-            Trace("sg-gt-enum") << "Ground term enumerate : " << n << std::endl;\r
-            terms.push_back( n );\r
-          }\r
-          vec.pop_back();\r
-          index = 0;\r
-        }\r
-      }else{\r
-        if( terms.size()>last_size ){\r
-          last_size = terms.size();\r
-          size_limit++;\r
-          for( unsigned i=0; i<vec.size(); i++ ){\r
-            vec[i] = 0;\r
-          }\r
-          vec_sum = -1;\r
-        }else{\r
-          return;\r
-        }\r
-      }\r
-    }\r
-  }else{\r
-    terms.push_back( n );\r
-  }\r
-}\r
-\r
-void ConjectureGenerator::getEnumeratePredUfTerm( Node n, unsigned num, std::vector< Node >& terms ) {\r
-  std::vector< Node > uf_terms;\r
-  getEnumerateUfTerm( n, num, uf_terms );\r
-  Node p = getPredicateForType( n.getType() );\r
-  for( unsigned i=0; i<uf_terms.size(); i++ ){\r
-    terms.push_back( NodeManager::currentNM()->mkNode( APPLY_UF, p, uf_terms[i] ) );\r
-  }\r
-}\r
-\r
-void ConjectureGenerator::processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth ) {\r
-  int score = considerCandidateConjecture( lhs, rhs );\r
-  if( score>0 ){\r
-    Trace("sg-conjecture") << "* Candidate conjecture : " << lhs << " == " << rhs << std::endl;\r
-    Trace("sg-conjecture-debug") << "     LHS, RHS generalization depth : " << lhs_depth << ", " << rhs_depth << std::endl;\r
-    Trace("sg-conjecture-debug") << "     confirmed = " << d_subs_confirmCount << ", #witnesses range = " << d_subs_confirmWitnessRange.size() << "." << std::endl;\r
-    Trace("sg-conjecture-debug") << "     #witnesses for ";\r
-    bool firstTime = true;\r
-    for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){\r
-      if( !firstTime ){\r
-        Trace("sg-conjecture-debug") << ", ";\r
-      }\r
-      Trace("sg-conjecture-debug") << it->first << " : " << it->second.size();\r
-      //if( it->second.size()==1 ){\r
-      //  Trace("sg-conjecture-debug") << " (" << it->second[0] << ")";\r
-      //}\r
-      Trace("sg-conjecture-debug2") << " (";\r
-      for( unsigned j=0; j<it->second.size(); j++ ){\r
-        if( j>0 ){ Trace("sg-conjecture-debug2") << " "; }\r
-        Trace("sg-conjecture-debug2") << d_ground_eqc_map[it->second[j]];\r
-      }\r
-      Trace("sg-conjecture-debug2") << ")";\r
-      firstTime = false;\r
-    }\r
-    Trace("sg-conjecture-debug") << std::endl;\r
-    Trace("sg-conjecture-debug") << "     unknown = " << d_subs_unkCount << std::endl;\r
-    //Assert( getUniversalRepresentative( rhs )==rhs );\r
-    //Assert( getUniversalRepresentative( lhs )==lhs );\r
-    d_waiting_conjectures_lhs.push_back( lhs );\r
-    d_waiting_conjectures_rhs.push_back( rhs );\r
-    d_waiting_conjectures_score.push_back( score );\r
-    d_waiting_conjectures[lhs].push_back( rhs );\r
-    d_waiting_conjectures[rhs].push_back( lhs );\r
-  }\r
-}\r
-\r
-int ConjectureGenerator::considerCandidateConjecture( TNode lhs, TNode rhs ) {\r
-  Assert( lhs.getType()==rhs.getType() );\r
-\r
-  Trace("sg-cconj-debug") << "Consider candidate conjecture : " << lhs << " == " << rhs << "?" << std::endl;\r
-  if( lhs==rhs ){\r
-    Trace("sg-cconj-debug") << "  -> trivial." << std::endl;\r
-    return -1;\r
-  }else{\r
-    if( lhs.getKind()==APPLY_CONSTRUCTOR && rhs.getKind()==APPLY_CONSTRUCTOR ){\r
-      Trace("sg-cconj-debug") << "  -> irrelevant by syntactic analysis." << std::endl;\r
-      return -1;\r
-    }\r
-    //variables of LHS must subsume variables of RHS\r
-    for( std::map< TypeNode, unsigned >::iterator it = d_pattern_var_id[rhs].begin(); it != d_pattern_var_id[rhs].end(); ++it ){\r
-      std::map< TypeNode, unsigned >::iterator itl = d_pattern_var_id[lhs].find( it->first );\r
-      if( itl!=d_pattern_var_id[lhs].end() ){\r
-        if( itl->second<it->second ){\r
-          Trace("sg-cconj-debug") << "  -> variables of sort " << it->first << " are not subsumed." << std::endl;\r
-          return -1;\r
-        }else{\r
-          Trace("sg-cconj-debug2") << "  variables of sort " << it->first << " are : " << itl->second << " vs " << it->second << std::endl;\r
-        }\r
-      }else{\r
-        Trace("sg-cconj-debug") << "  -> has no variables of sort " << it->first << "." << std::endl;\r
-        return -1;\r
-      }\r
-    }\r
-\r
-    //currently active conjecture?\r
-    std::map< Node, std::vector< Node > >::iterator iteq = d_eq_conjectures.find( lhs );\r
-    if( iteq!=d_eq_conjectures.end() ){\r
-      if( std::find( iteq->second.begin(), iteq->second.end(), rhs )!=iteq->second.end() ){\r
-        Trace("sg-cconj-debug") << "  -> this conjecture is already active." << std::endl;\r
-        return -1;\r
-      }\r
-    }\r
-    //current a waiting conjecture?\r
-    std::map< Node, std::vector< Node > >::iterator itw = d_waiting_conjectures.find( lhs );\r
-    if( itw!=d_waiting_conjectures.end() ){\r
-      if( std::find( itw->second.begin(), itw->second.end(), rhs )!=itw->second.end() ){\r
-        Trace("sg-cconj-debug") << "  -> already are considering this conjecture." << std::endl;\r
-        return -1;\r
-      }\r
-    }\r
-    //check if canonical representation (should be, but for efficiency this is not guarenteed)\r
-    //if( options::conjectureFilterCanonical() && ( getUniversalRepresentative( lhs )!=lhs || getUniversalRepresentative( rhs )!=rhs ) ){\r
-    //  Trace("sg-cconj") << "  -> after processing, not canonical." << std::endl;\r
-    //  return -1;\r
-    //}\r
-\r
-    int score;\r
-    bool scoreSet = false;\r
-\r
-    Trace("sg-cconj") << "Consider possible candidate conjecture : " << lhs << " == " << rhs << "?" << std::endl;\r
-    //find witness for counterexample, if possible\r
-    if( options::conjectureFilterModel() ){\r
-      Assert( d_rel_pattern_var_sum.find( lhs )!=d_rel_pattern_var_sum.end() );\r
-      Trace("sg-cconj-debug") << "Notify substitutions over " << d_rel_pattern_var_sum[lhs] << " variables." << std::endl;\r
-      std::map< TNode, TNode > subs;\r
-      d_subs_confirmCount = 0;\r
-      d_subs_confirmWitnessRange.clear();\r
-      d_subs_confirmWitnessDomain.clear();\r
-      d_subs_unkCount = 0;\r
-      if( !d_rel_pattern_subs_index[lhs].notifySubstitutions( this, subs, rhs, d_rel_pattern_var_sum[lhs] ) ){\r
-        Trace("sg-cconj") << "  -> found witness that falsifies the conjecture." << std::endl;\r
-        return -1;\r
-      }\r
-      //score is the minimum number of distinct substitutions for a variable\r
-      for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){\r
-        int num = (int)it->second.size();\r
-        if( !scoreSet || num<score ){\r
-          score = num;\r
-          scoreSet = true;\r
-        }\r
-      }\r
-      if( !scoreSet ){\r
-        score = 0;\r
-      }\r
-      Trace("sg-cconj") << "     confirmed = " << d_subs_confirmCount << ", #witnesses range = " << d_subs_confirmWitnessRange.size() << "." << std::endl;\r
-      for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){\r
-        Trace("sg-cconj") << "     #witnesses for " << it->first << " : " << it->second.size() << std::endl;\r
-      }\r
-    }else{\r
-      score = 1;\r
-    }\r
-\r
-    Trace("sg-cconj") << "  -> SUCCESS." << std::endl;\r
-    Trace("sg-cconj") << "     score : " << score << std::endl;\r
-\r
-    return score;\r
-  }\r
-}\r
-\r
-bool ConjectureGenerator::notifySubstitution( TNode glhs, std::map< TNode, TNode >& subs, TNode rhs ) {\r
-  if( Trace.isOn("sg-cconj-debug") ){\r
-    Trace("sg-cconj-debug") << "Ground eqc for LHS : " << glhs << ", based on substituion: " << std::endl;\r
-    for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
-      Assert( getRepresentative( it->second )==it->second );\r
-      Trace("sg-cconj-debug") << "  " << it->first << " -> " << it->second << std::endl;\r
-    }\r
-  }\r
-  Trace("sg-cconj-debug") << "Evaluate RHS : : " << rhs << std::endl;\r
-  //get the representative of rhs with substitution subs\r
-  TNode grhs = getTermDatabase()->evaluateTerm( rhs, subs, true );\r
-  Trace("sg-cconj-debug") << "...done evaluating term, got : " << grhs << std::endl;\r
-  if( !grhs.isNull() ){\r
-    if( glhs!=grhs ){\r
-      Trace("sg-cconj-debug") << "Ground eqc for RHS : " << grhs << std::endl;\r
-      //check based on ground terms\r
-      std::map< TNode, Node >::iterator itl = d_ground_eqc_map.find( glhs );\r
-      if( itl!=d_ground_eqc_map.end() ){\r
-        std::map< TNode, Node >::iterator itr = d_ground_eqc_map.find( grhs );\r
-        if( itr!=d_ground_eqc_map.end() ){\r
-          Trace("sg-cconj-debug") << "We have ground terms " << itl->second << " and " << itr->second << "." << std::endl;\r
-          if( itl->second.isConst() && itr->second.isConst() ){\r
-            Trace("sg-cconj-debug") << "...disequal constants." << std::endl;\r
-            Trace("sg-cconj-witness") << "  Witness of falsification : " << itl->second << " != " << itr->second << ", substutition is : " << std::endl;\r
-            for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
-              Trace("sg-cconj-witness") << "    " << it->first << " -> " << it->second << std::endl;\r
-            }\r
-            return false;\r
-          }\r
-        }\r
-      }\r
-    }\r
-    Trace("sg-cconj-debug") << "RHS is identical." << std::endl;\r
-    bool isGroundSubs = true;\r
-    for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
-      std::map< TNode, Node >::iterator git = d_ground_eqc_map.find( it->second );\r
-      if( git==d_ground_eqc_map.end() ){\r
-        isGroundSubs = false;\r
-        break;\r
-      }\r
-    }\r
-    if( isGroundSubs ){\r
-      if( glhs==grhs ){\r
-        Trace("sg-cconj-witness") << "  Witnessed " << glhs << " == " << grhs << ", substutition is : " << std::endl;\r
-        for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){\r
-          Trace("sg-cconj-witness") << "    " << it->first << " -> " << it->second << std::endl;\r
-          if( std::find( d_subs_confirmWitnessDomain[it->first].begin(), d_subs_confirmWitnessDomain[it->first].end(), it->second )==d_subs_confirmWitnessDomain[it->first].end() ){\r
-            d_subs_confirmWitnessDomain[it->first].push_back( it->second );\r
-          }\r
-        }\r
-        d_subs_confirmCount++;\r
-        if( std::find( d_subs_confirmWitnessRange.begin(), d_subs_confirmWitnessRange.end(), glhs )==d_subs_confirmWitnessRange.end() ){\r
-          d_subs_confirmWitnessRange.push_back( glhs );\r
-        }\r
-      }else{\r
-        if( optFilterUnknown() ){\r
-          Trace("sg-cconj-debug") << "...ground substitution giving terms that are neither equal nor disequal." << std::endl;\r
-          return false;\r
-        }\r
-      }\r
-    }\r
-  }else{\r
-    Trace("sg-cconj-debug") << "(could not ground eqc for RHS)." << std::endl;\r
-  }\r
-  return true;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-void TermGenerator::reset( TermGenEnv * s, TypeNode tn ) {\r
-  Assert( d_children.empty() );\r
-  d_typ = tn;\r
-  d_status = 0;\r
-  d_status_num = 0;\r
-  d_children.clear();\r
-  Trace("sg-gen-tg-debug2") << "...add to context " << this << std::endl;\r
-  d_id = s->d_tg_id;\r
-  s->changeContext( true );\r
-}\r
-\r
-bool TermGenerator::getNextTerm( TermGenEnv * s, unsigned depth ) {\r
-  if( Trace.isOn("sg-gen-tg-debug2") ){\r
-    Trace("sg-gen-tg-debug2") << this << " getNextTerm depth " << depth << " : status = " << d_status << ", num = " << d_status_num;\r
-    if( d_status==5 ){\r
-      TNode f = s->getTgFunc( d_typ, d_status_num );\r
-      Trace("sg-gen-tg-debug2") << ", f = " << f;\r
-      Trace("sg-gen-tg-debug2") << ", #args = " << s->d_func_args[f].size();\r
-      Trace("sg-gen-tg-debug2") << ", childNum = " << d_status_child_num;\r
-      Trace("sg-gen-tg-debug2") << ", #children = " << d_children.size();\r
-    }\r
-    Trace("sg-gen-tg-debug2") << std::endl;\r
-  }\r
-\r
-  if( d_status==0 ){\r
-    d_status++;\r
-    if( !d_typ.isNull() ){\r
-      if( s->allowVar( d_typ ) ){\r
-        //allocate variable\r
-        d_status_num = s->d_var_id[d_typ];\r
-        s->addVar( d_typ );\r
-        Trace("sg-gen-tg-debug2") << this << " ...return unique var #" << d_status_num << std::endl;\r
-        return s->considerCurrentTerm() ? true : getNextTerm( s, depth );\r
-      }else{\r
-        //check allocating new variable\r
-        d_status++;\r
-        d_status_num = -1;\r
-        if( s->d_gen_relevant_terms ){\r
-          s->d_tg_gdepth++;\r
-        }\r
-        return getNextTerm( s, depth );\r
-      }\r
-    }else{\r
-      d_status = 4;\r
-      d_status_num = -1;\r
-      return getNextTerm( s, depth );\r
-    }\r
-  }else if( d_status==2 ){\r
-    //cleanup previous information\r
-    //if( d_status_num>=0 ){\r
-    //  s->d_var_eq_tg[d_status_num].pop_back();\r
-    //}\r
-    //check if there is another variable\r
-    if( (d_status_num+1)<(int)s->getNumTgVars( d_typ ) ){\r
-      d_status_num++;\r
-      //we have equated two variables\r
-      //s->d_var_eq_tg[d_status_num].push_back( d_id );\r
-      Trace("sg-gen-tg-debug2") << this << "...consider other var #" << d_status_num << std::endl;\r
-      return s->considerCurrentTerm() ? true : getNextTerm( s, depth );\r
-    }else{\r
-      if( s->d_gen_relevant_terms ){\r
-        s->d_tg_gdepth--;\r
-      }\r
-      d_status++;\r
-      return getNextTerm( s, depth );\r
-    }\r
-  }else if( d_status==4 ){\r
-    d_status++;\r
-    if( depth>0 && (d_status_num+1)<(int)s->getNumTgFuncs( d_typ ) ){\r
-      d_status_num++;\r
-      d_status_child_num = 0;\r
-      Trace("sg-gen-tg-debug2") << this << "...consider function " << s->getTgFunc( d_typ, d_status_num ) << std::endl;\r
-      s->d_tg_gdepth++;\r
-      if( !s->considerCurrentTerm() ){\r
-        s->d_tg_gdepth--;\r
-        //don't consider this function\r
-        d_status--;\r
-      }else{\r
-        //we have decided on a function application\r
-      }\r
-      return getNextTerm( s, depth );\r
-    }else{\r
-      //do not choose function applications at depth 0\r
-      d_status++;\r
-      return getNextTerm( s, depth );\r
-    }\r
-  }else if( d_status==5 ){\r
-    //iterating over arguments\r
-    TNode f = s->getTgFunc( d_typ, d_status_num );\r
-    if( d_status_child_num<0 ){\r
-      //no more arguments\r
-      s->d_tg_gdepth--;\r
-      d_status--;\r
-      return getNextTerm( s, depth );\r
-    }else if( d_status_child_num==(int)s->d_func_args[f].size() ){\r
-      d_status_child_num--;\r
-      return s->considerCurrentTermCanon( d_id ) ? true : getNextTerm( s, depth );\r
-      //return true;\r
-    }else{\r
-      Assert( d_status_child_num<(int)s->d_func_args[f].size() );\r
-      if( d_status_child_num==(int)d_children.size() ){\r
-        d_children.push_back( s->d_tg_id );\r
-        Assert( s->d_tg_alloc.find( s->d_tg_id )==s->d_tg_alloc.end() );\r
-        s->d_tg_alloc[d_children[d_status_child_num]].reset( s, s->d_func_args[f][d_status_child_num] );\r
-        return getNextTerm( s, depth );\r
-      }else{\r
-        Assert( d_status_child_num+1==(int)d_children.size() );\r
-        if( s->d_tg_alloc[d_children[d_status_child_num]].getNextTerm( s, depth-1 ) ){\r
-          d_status_child_num++;\r
-          return getNextTerm( s, depth );\r
-        }else{\r
-          d_children.pop_back();\r
-          d_status_child_num--;\r
-          return getNextTerm( s, depth );\r
-        }\r
-      }\r
-    }\r
-  }else if( d_status==1 || d_status==3 ){\r
-    if( d_status==1 ){\r
-      s->removeVar( d_typ );\r
-      Assert( d_status_num==(int)s->d_var_id[d_typ] );\r
-      //check if there is only one feasible equivalence class.  if so, don't make pattern any more specific.\r
-      //unsigned i = s->d_ccand_eqc[0].size()-1;\r
-      //if( s->d_ccand_eqc[0][i].size()==1 && s->d_ccand_eqc[1][i].empty() ){\r
-      //  d_status = 6;\r
-      //  return getNextTerm( s, depth );\r
-      //}\r
-      s->d_tg_gdepth++;\r
-    }\r
-    d_status++;\r
-    d_status_num = -1;\r
-    return getNextTerm( s, depth );\r
-  }else{\r
-    //clean up\r
-    Assert( d_children.empty() );\r
-    Trace("sg-gen-tg-debug2") << "...remove from context " << this << std::endl;\r
-    s->changeContext( false );\r
-    Assert( d_id==s->d_tg_id );\r
-    return false;\r
-  }\r
-}\r
-\r
-void TermGenerator::resetMatching( TermGenEnv * s, TNode eqc, unsigned mode ) {\r
-  d_match_status = 0;\r
-  d_match_status_child_num = 0;\r
-  d_match_children.clear();\r
-  d_match_children_end.clear();\r
-  d_match_mode = mode;\r
-  //if this term generalizes, it must generalize a non-ground term\r
-  //if( (d_match_mode & ( 1 << 2 ))!=0 && s->isGroundEqc( eqc ) && d_status==5 ){\r
-  //  d_match_status = -1;\r
-  //}\r
-}\r
-\r
-bool TermGenerator::getNextMatch( TermGenEnv * s, TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs ) {\r
-  if( d_match_status<0 ){\r
-    return false;\r
-  }\r
-  if( Trace.isOn("sg-gen-tg-match") ){\r
-    Trace("sg-gen-tg-match") << "Matching ";\r
-    debugPrint( s, "sg-gen-tg-match", "sg-gen-tg-match" );\r
-    Trace("sg-gen-tg-match") << " with eqc e" << s->d_cg->d_em[eqc] << "..." << std::endl;\r
-    Trace("sg-gen-tg-match") << "   mstatus = " << d_match_status;\r
-    if( d_status==5 ){\r
-      TNode f = s->getTgFunc( d_typ, d_status_num );\r
-      Trace("sg-gen-tg-debug2") << ", f = " << f;\r
-      Trace("sg-gen-tg-debug2") << ", #args = " << s->d_func_args[f].size();\r
-      Trace("sg-gen-tg-debug2") << ", mchildNum = " << d_match_status_child_num;\r
-      Trace("sg-gen-tg-debug2") << ", #mchildren = " << d_match_children.size();\r
-    }\r
-    Trace("sg-gen-tg-debug2") << ", current substitution : {";\r
-    for( std::map< TypeNode, std::map< unsigned, TNode > >::iterator itt = subs.begin(); itt != subs.end(); ++itt ){\r
-      for( std::map< unsigned, TNode >::iterator it = itt->second.begin(); it != itt->second.end(); ++it ){\r
-        Trace("sg-gen-tg-debug2")  << " " << it->first << " -> e" << s->d_cg->d_em[it->second];\r
-      }\r
-    }\r
-    Trace("sg-gen-tg-debug2") << " } " << std::endl;\r
-  }\r
-  if( d_status==1 ){\r
-    //a variable\r
-    if( d_match_status==0 ){\r
-      d_match_status++;\r
-      if( (d_match_mode & ( 1 << 1 ))!=0 ){\r
-        //only ground terms\r
-        if( !s->isGroundEqc( eqc ) ){\r
-          return false;\r
-        }\r
-      }else if( (d_match_mode & ( 1 << 2 ))!=0 ){\r
-        //only non-ground terms\r
-        //if( s->isGroundEqc( eqc ) ){\r
-        //  return false;\r
-        //}\r
-      }\r
-      //store the match : restricted if match_mode.0 = 1\r
-      if( (d_match_mode & ( 1 << 0 ))!=0 ){\r
-        std::map< TNode, bool >::iterator it = rev_subs.find( eqc );\r
-        if( it==rev_subs.end() ){\r
-          rev_subs[eqc] = true;\r
-        }else{\r
-          return false;\r
-        }\r
-      }\r
-      Assert( subs[d_typ].find( d_status_num )==subs[d_typ].end() );\r
-      subs[d_typ][d_status_num] = eqc;\r
-      return true;\r
-    }else{\r
-      //clean up\r
-      subs[d_typ].erase( d_status_num );\r
-      if( (d_match_mode & ( 1 << 0 ))!=0 ){\r
-        rev_subs.erase( eqc );\r
-      }\r
-      return false;\r
-    }\r
-  }else if( d_status==2 ){\r
-    if( d_match_status==0 ){\r
-      d_match_status++;\r
-      Assert( d_status_num<(int)s->getNumTgVars( d_typ ) );\r
-      std::map< unsigned, TNode >::iterator it = subs[d_typ].find( d_status_num );\r
-      Assert( it!=subs[d_typ].end() );\r
-      return it->second==eqc;\r
-    }else{\r
-      return false;\r
-    }\r
-  }else if( d_status==5 ){\r
-    //Assert( d_match_children.size()<=d_children.size() );\r
-    //enumerating over f-applications in eqc\r
-    if( d_match_status_child_num<0 ){\r
-      return false;\r
-    }else if( d_match_status==0 ){\r
-      //set up next binding\r
-      if( d_match_status_child_num==(int)d_match_children.size() ){\r
-        if( d_match_status_child_num==0 ){\r
-          //initial binding\r
-          TNode f = s->getTgFunc( d_typ, d_status_num );\r
-          std::map< TNode, TermArgTrie >::iterator it = s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.find( eqc );\r
-          if( it!=s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.end() ){\r
-            d_match_children.push_back( it->second.d_data.begin() );\r
-            d_match_children_end.push_back( it->second.d_data.end() );\r
-          }else{\r
-            d_match_status++;\r
-            d_match_status_child_num--;\r
-            return getNextMatch( s, eqc, subs, rev_subs );\r
-          }\r
-        }else{\r
-          d_match_children.push_back( d_match_children[d_match_status_child_num-1]->second.d_data.begin() );\r
-          d_match_children_end.push_back( d_match_children[d_match_status_child_num-1]->second.d_data.end() );\r
-        }\r
-      }\r
-      d_match_status++;\r
-      Assert( d_match_status_child_num+1==(int)d_match_children.size() );\r
-      if( d_match_children[d_match_status_child_num]==d_match_children_end[d_match_status_child_num] ){\r
-        //no more arguments to bind\r
-        d_match_children.pop_back();\r
-        d_match_children_end.pop_back();\r
-        d_match_status_child_num--;\r
-        return getNextMatch( s, eqc, subs, rev_subs );\r
-      }else{\r
-        if( d_match_status_child_num==(int)d_children.size() ){\r
-          //successfully matched all children\r
-          d_match_children.pop_back();\r
-          d_match_children_end.pop_back();\r
-          d_match_status_child_num--;\r
-          return true;//return d_match_children[d_match_status]!=d_match_children_end[d_match_status];\r
-        }else{\r
-          //do next binding\r
-          s->d_tg_alloc[d_children[d_match_status_child_num]].resetMatching( s, d_match_children[d_match_status_child_num]->first, d_match_mode );\r
-          return getNextMatch( s, eqc, subs, rev_subs );\r
-        }\r
-      }\r
-    }else{\r
-      Assert( d_match_status==1 );\r
-      Assert( d_match_status_child_num+1==(int)d_match_children.size() );\r
-      Assert( d_match_children[d_match_status_child_num]!=d_match_children_end[d_match_status_child_num] );\r
-      d_match_status--;\r
-      if( s->d_tg_alloc[d_children[d_match_status_child_num]].getNextMatch( s, d_match_children[d_match_status_child_num]->first, subs, rev_subs ) ){\r
-        d_match_status_child_num++;\r
-        return getNextMatch( s, eqc, subs, rev_subs );\r
-      }else{\r
-        //iterate\r
-        d_match_children[d_match_status_child_num]++;\r
-        return getNextMatch( s, eqc, subs, rev_subs );\r
-      }\r
-    }\r
-  }\r
-  Assert( false );\r
-  return false;\r
-}\r
-\r
-unsigned TermGenerator::getDepth( TermGenEnv * s ) {\r
-  if( d_status==5 ){\r
-    unsigned maxd = 0;\r
-    for( unsigned i=0; i<d_children.size(); i++ ){\r
-      unsigned d = s->d_tg_alloc[d_children[i]].getDepth( s );\r
-      if( d>maxd ){\r
-        maxd = d;\r
-      }\r
-    }\r
-    return 1+maxd;\r
-  }else{\r
-    return 0;\r
-  }\r
-}\r
-\r
-unsigned TermGenerator::calculateGeneralizationDepth( TermGenEnv * s, std::map< TypeNode, std::vector< int > >& fvs ) {\r
-  if( d_status==5 ){\r
-    unsigned sum = 1;\r
-    for( unsigned i=0; i<d_children.size(); i++ ){\r
-      sum += s->d_tg_alloc[d_children[i]].calculateGeneralizationDepth( s, fvs );\r
-    }\r
-    return sum;\r
-  }else{\r
-    Assert( d_status==2 || d_status==1 );\r
-    std::map< TypeNode, std::vector< int > >::iterator it = fvs.find( d_typ );\r
-    if( it!=fvs.end() ){\r
-      if( std::find( it->second.begin(), it->second.end(), d_status_num )!=it->second.end() ){\r
-        return 1;\r
-      }\r
-    }\r
-    fvs[d_typ].push_back( d_status_num );\r
-    return 0;\r
-  }\r
-}\r
-\r
-unsigned TermGenerator::getGeneralizationDepth( TermGenEnv * s ) {\r
-  //if( s->d_gen_relevant_terms ){\r
-  //  return s->d_tg_gdepth;\r
-  //}else{\r
-    std::map< TypeNode, std::vector< int > > fvs;\r
-    return calculateGeneralizationDepth( s, fvs );\r
-  //}\r
-}\r
-\r
-Node TermGenerator::getTerm( TermGenEnv * s ) {\r
-  if( d_status==1 || d_status==2 ){\r
-    Assert( !d_typ.isNull() );\r
-    return s->getFreeVar( d_typ, d_status_num );\r
-  }else if( d_status==5 ){\r
-    Node f = s->getTgFunc( d_typ, d_status_num );\r
-    if( d_children.size()==s->d_func_args[f].size() ){\r
-      std::vector< Node > children;\r
-      if( s->d_tg_func_param[f] ){\r
-        children.push_back( f );\r
-      }\r
-      for( unsigned i=0; i<d_children.size(); i++ ){\r
-        Node nc = s->d_tg_alloc[d_children[i]].getTerm( s );\r
-        if( nc.isNull() ){\r
-          return Node::null();\r
-        }else{\r
-          //Assert( nc.getType()==s->d_func_args[f][i] );\r
-          children.push_back( nc );\r
-        }\r
-      }\r
-      return NodeManager::currentNM()->mkNode( s->d_func_kind[f], children );\r
-    }\r
-  }else{\r
-    Assert( false );\r
-  }\r
-  return Node::null();\r
-}\r
-\r
-void TermGenerator::debugPrint( TermGenEnv * s, const char * c, const char * cd ) {\r
-  Trace(cd) << "[*" << d_id << "," << d_status << "]:";\r
-  if( d_status==1 || d_status==2 ){\r
-    Trace(c) << s->getFreeVar( d_typ, d_status_num );\r
-  }else if( d_status==5 ){\r
-    TNode f = s->getTgFunc( d_typ, d_status_num );\r
-    Trace(c) << "(" << f;\r
-    for( unsigned i=0; i<d_children.size(); i++ ){\r
-      Trace(c) << " ";\r
-       s->d_tg_alloc[d_children[i]].debugPrint( s, c, cd );\r
-    }\r
-    if( d_children.size()<s->d_func_args[f].size() ){\r
-      Trace(c) << " ...";\r
-    }\r
-    Trace(c) << ")";\r
-  }else{\r
-    Trace(c) << "???";\r
-  }\r
-}\r
-\r
-void TermGenEnv::collectSignatureInformation() {\r
-  d_typ_tg_funcs.clear();\r
-  d_funcs.clear();\r
-  d_func_kind.clear();\r
-  d_func_args.clear();\r
-  TypeNode tnull;\r
-  for( std::map< Node, TermArgTrie >::iterator it = getTermDatabase()->d_func_map_trie.begin(); it != getTermDatabase()->d_func_map_trie.end(); ++it ){\r
-    if( !getTermDatabase()->d_op_map[it->first].empty() ){\r
-      Node nn = getTermDatabase()->d_op_map[it->first][0];\r
-      if( d_cg->isHandledTerm( nn ) && nn.getKind()!=APPLY_SELECTOR_TOTAL && !nn.getType().isBoolean() ){\r
-        bool do_enum = true;\r
-        //check if we have enumerated ground terms\r
-        if( nn.getKind()==APPLY_UF ){\r
-          if( !d_cg->hasEnumeratedUf( nn ) ){\r
-            do_enum = false;\r
-          }\r
-        }\r
-        if( do_enum ){\r
-          d_funcs.push_back( it->first );\r
-          for( unsigned i=0; i<nn.getNumChildren(); i++ ){\r
-            d_func_args[it->first].push_back( nn[i].getType() );\r
-          }\r
-          d_func_kind[it->first] = nn.getKind();\r
-          d_typ_tg_funcs[tnull].push_back( it->first );\r
-          d_typ_tg_funcs[nn.getType()].push_back( it->first );\r
-          d_tg_func_param[it->first] = ( nn.getMetaKind() == kind::metakind::PARAMETERIZED );\r
-          Trace("sg-rel-sig") << "Will enumerate function applications of : " << it->first << ", #args = " << d_func_args[it->first].size() << ", kind = " << nn.getKind() << std::endl;\r
-          getTermDatabase()->computeUfEqcTerms( it->first );\r
-        }\r
-      }\r
-    }\r
-  }\r
-  //shuffle functions\r
-  for( std::map< TypeNode, std::vector< TNode > >::iterator it = d_typ_tg_funcs.begin(); it != d_typ_tg_funcs.end(); ++it ){\r
-    std::random_shuffle( it->second.begin(), it->second.end() );\r
-    if( it->first.isNull() ){\r
-      Trace("sg-gen-tg-debug") << "In this order : ";\r
-      for( unsigned i=0; i<it->second.size(); i++ ){\r
-        Trace("sg-gen-tg-debug") << it->second[i] << " ";\r
-      }\r
-      Trace("sg-gen-tg-debug") << std::endl;\r
-    }\r
-  }\r
-}\r
-\r
-void TermGenEnv::reset( unsigned depth, bool genRelevant, TypeNode tn ) {\r
-  Assert( d_tg_alloc.empty() );\r
-  d_tg_alloc.clear();\r
-\r
-  if( genRelevant ){\r
-    for( unsigned i=0; i<2; i++ ){\r
-      d_ccand_eqc[i].clear();\r
-      d_ccand_eqc[i].push_back( d_relevant_eqc[i] );\r
-    }\r
-  }\r
-\r
-  d_tg_id = 0;\r
-  d_tg_gdepth = 0;\r
-  d_tg_gdepth_limit = depth;\r
-  d_gen_relevant_terms = genRelevant;\r
-  d_tg_alloc[0].reset( this, tn );\r
-}\r
-\r
-bool TermGenEnv::getNextTerm() {\r
-  if( d_tg_alloc[0].getNextTerm( this, d_tg_gdepth_limit ) ){\r
-    Assert( (int)d_tg_alloc[0].getGeneralizationDepth( this )<=d_tg_gdepth_limit );\r
-    if( (int)d_tg_alloc[0].getGeneralizationDepth( this )!=d_tg_gdepth_limit ){\r
-      return getNextTerm();\r
-    }else{\r
-      return true;\r
-    }\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-//reset matching\r
-void TermGenEnv::resetMatching( TNode eqc, unsigned mode ) {\r
-  d_tg_alloc[0].resetMatching( this, eqc, mode );\r
-}\r
-\r
-//get next match\r
-bool TermGenEnv::getNextMatch( TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs ) {\r
-  return d_tg_alloc[0].getNextMatch( this, eqc, subs, rev_subs );\r
-}\r
-\r
-//get term\r
-Node TermGenEnv::getTerm() {\r
-  return d_tg_alloc[0].getTerm( this );\r
-}\r
-\r
-void TermGenEnv::debugPrint( const char * c, const char * cd ) {\r
-  d_tg_alloc[0].debugPrint( this, c, cd );\r
-}\r
-\r
-unsigned TermGenEnv::getNumTgVars( TypeNode tn ) {\r
-  return d_var_id[tn];\r
-}\r
-\r
-bool TermGenEnv::allowVar( TypeNode tn ) {\r
-  std::map< TypeNode, unsigned >::iterator it = d_var_limit.find( tn );\r
-  if( it==d_var_limit.end() ){\r
-    return true;\r
-  }else{\r
-    return d_var_id[tn]<it->second;\r
-  }\r
-}\r
-\r
-void TermGenEnv::addVar( TypeNode tn ) {\r
-  d_var_id[tn]++;\r
-}\r
-\r
-void TermGenEnv::removeVar( TypeNode tn ) {\r
-  d_var_id[tn]--;\r
-  //d_var_eq_tg.pop_back();\r
-  //d_var_tg.pop_back();\r
-}\r
-\r
-unsigned TermGenEnv::getNumTgFuncs( TypeNode tn ) {\r
-  return d_typ_tg_funcs[tn].size();\r
-}\r
-\r
-TNode TermGenEnv::getTgFunc( TypeNode tn, unsigned i ) {\r
-  return d_typ_tg_funcs[tn][i];\r
-}\r
-\r
-Node TermGenEnv::getFreeVar( TypeNode tn, unsigned i ) {\r
-  return d_cg->getFreeVar( tn, i );\r
-}\r
-\r
-bool TermGenEnv::considerCurrentTerm() {\r
-  Assert( !d_tg_alloc.empty() );\r
-\r
-  //if generalization depth is too large, don't consider it\r
-  unsigned i = d_tg_alloc.size();\r
-  Trace("sg-gen-tg-debug") << "Consider term ";\r
-  d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
-  Trace("sg-gen-tg-debug") << "?  curr term size = " << d_tg_alloc.size() << ", last status = " << d_tg_alloc[i-1].d_status;\r
-  Trace("sg-gen-tg-debug") << std::endl;\r
-\r
-  if( d_tg_gdepth_limit>=0 && d_tg_alloc[0].getGeneralizationDepth( this )>(unsigned)d_tg_gdepth_limit ){\r
-    Trace("sg-gen-consider-term") << "-> generalization depth of ";\r
-    d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-tg-debug" );\r
-    Trace("sg-gen-consider-term") << " is too high " << d_tg_gdepth << " " << d_tg_alloc[0].getGeneralizationDepth( this ) << ", do not consider." << std::endl;\r
-    return false;\r
-  }\r
-\r
-  //----optimizations\r
-  /*\r
-  if( d_tg_alloc[i-1].d_status==1 ){\r
-  }else if( d_tg_alloc[i-1].d_status==2 ){\r
-  }else if( d_tg_alloc[i-1].d_status==5 ){\r
-  }else{\r
-    Trace("sg-gen-tg-debug") << "Bad tg: " << &d_tg_alloc[i-1] << std::endl;\r
-    Assert( false );\r
-  }\r
-  */\r
-  //if equated two variables, first check if context-independent TODO\r
-  //----end optimizations\r
-\r
-\r
-  //check based on which candidate equivalence classes match\r
-  if( d_gen_relevant_terms ){\r
-    Trace("sg-gen-tg-debug") << "Filter based on relevant ground EQC";\r
-    Trace("sg-gen-tg-debug") << ", #eqc to try = " << d_ccand_eqc[0][i-1].size() << "/" << d_ccand_eqc[1][i-1].size() << std::endl;\r
-\r
-    Assert( d_ccand_eqc[0].size()>=2 );\r
-    Assert( d_ccand_eqc[0].size()==d_ccand_eqc[1].size() );\r
-    Assert( d_ccand_eqc[0].size()==d_tg_id+1 );\r
-    Assert( d_tg_id==d_tg_alloc.size() );\r
-    for( unsigned r=0; r<2; r++ ){\r
-      d_ccand_eqc[r][i].clear();\r
-    }\r
-\r
-    //re-check feasibility of EQC\r
-    for( unsigned r=0; r<2; r++ ){\r
-      for( unsigned j=0; j<d_ccand_eqc[r][i-1].size(); j++ ){\r
-        std::map< TypeNode, std::map< unsigned, TNode > > subs;\r
-        std::map< TNode, bool > rev_subs;\r
-        unsigned mode;\r
-        if( r==0 ){\r
-          mode = d_cg->optReqDistinctVarPatterns() ? ( 1 << 0 ) : 0;\r
-          mode = mode | (1 << 2 );\r
-        }else{\r
-          mode =  1 << 1;\r
-        }\r
-        d_tg_alloc[0].resetMatching( this, d_ccand_eqc[r][i-1][j], mode );\r
-        if( d_tg_alloc[0].getNextMatch( this, d_ccand_eqc[r][i-1][j], subs, rev_subs ) ){\r
-          d_ccand_eqc[r][i].push_back( d_ccand_eqc[r][i-1][j] );\r
-        }\r
-      }\r
-    }\r
-    for( unsigned r=0; r<2; r++ ){\r
-      Trace("sg-gen-tg-debug") << "Current eqc of type " << r << " : ";\r
-      for( unsigned j=0; j<d_ccand_eqc[r][i].size(); j++ ){\r
-        Trace("sg-gen-tg-debug") << "e" << d_cg->d_em[d_ccand_eqc[r][i][j]] << " ";\r
-      }\r
-      Trace("sg-gen-tg-debug") << std::endl;\r
-    }\r
-    if( options::conjectureFilterActiveTerms() && d_ccand_eqc[0][i].empty() ){\r
-      Trace("sg-gen-consider-term") << "Do not consider term of form ";\r
-      d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-consider-term-debug" );\r
-      Trace("sg-gen-consider-term") << " since no relevant EQC matches it." << std::endl;\r
-      return false;\r
-    }\r
-    if( options::conjectureFilterModel() && d_ccand_eqc[1][i].empty() ){\r
-      Trace("sg-gen-consider-term") << "Do not consider term of form ";\r
-      d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-consider-term-debug" );\r
-      Trace("sg-gen-consider-term") << " since no ground EQC matches it." << std::endl;\r
-      return false;\r
-    }\r
-  }\r
-  Trace("sg-gen-tg-debug") << "Will consider term ";\r
-  d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
-  Trace("sg-gen-tg-debug") << std::endl;\r
-  Trace("sg-gen-consider-term-debug") << std::endl;\r
-  return true;\r
-}\r
-\r
-void TermGenEnv::changeContext( bool add ) {\r
-  if( add ){\r
-    for( unsigned r=0; r<2; r++ ){\r
-      d_ccand_eqc[r].push_back( std::vector< TNode >() );\r
-    }\r
-    d_tg_id++;\r
-  }else{\r
-    for( unsigned r=0; r<2; r++ ){\r
-      d_ccand_eqc[r].pop_back();\r
-    }\r
-    d_tg_id--;\r
-    Assert( d_tg_alloc.find( d_tg_id )!=d_tg_alloc.end() );\r
-    d_tg_alloc.erase( d_tg_id );\r
-  }\r
-}\r
-\r
-bool TermGenEnv::considerCurrentTermCanon( unsigned tg_id ){\r
-  Assert( tg_id<d_tg_alloc.size() );\r
-  if( options::conjectureFilterCanonical() ){\r
-    //check based on a canonicity of the term (if there is one)\r
-    Trace("sg-gen-tg-debug") << "Consider term canon ";\r
-    d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );\r
-    Trace("sg-gen-tg-debug") << ", tg is [" << tg_id << "]..." << std::endl;\r
-\r
-    Node ln = d_tg_alloc[tg_id].getTerm( this );\r
-    Trace("sg-gen-tg-debug") << "Term is " << ln << std::endl;\r
-    return d_cg->considerTermCanon( ln, d_gen_relevant_terms );\r
-  }\r
-  return true;\r
-}\r
-\r
-bool TermGenEnv::isRelevantFunc( Node f ) {\r
-  return std::find( d_funcs.begin(), d_funcs.end(), f )!=d_funcs.end();\r
-}\r
-TermDb * TermGenEnv::getTermDatabase() {\r
-  return d_cg->getTermDatabase();\r
-}\r
-Node TermGenEnv::getGroundEqc( TNode r ) {\r
-  return d_cg->getGroundEqc( r );\r
-}\r
-bool TermGenEnv::isGroundEqc( TNode r ){\r
-  return d_cg->isGroundEqc( r );\r
-}\r
-bool TermGenEnv::isGroundTerm( TNode n ){\r
-  return d_cg->isGroundTerm( n );\r
-}\r
-\r
-\r
-void SubstitutionIndex::addSubstitution( TNode eqc, std::vector< TNode >& vars, std::vector< TNode >& terms, unsigned i ) {\r
-  if( i==vars.size() ){\r
-    d_var = eqc;\r
-  }else{\r
-    Assert( d_var.isNull() || d_var==vars[i] );\r
-    d_var = vars[i];\r
-    d_children[terms[i]].addSubstitution( eqc, vars, terms, i+1 );\r
-  }\r
-}\r
-\r
-bool SubstitutionIndex::notifySubstitutions( ConjectureGenerator * s, std::map< TNode, TNode >& subs, TNode rhs, unsigned numVars, unsigned i ) {\r
-  if( i==numVars ){\r
-    Assert( d_children.empty() );\r
-    return s->notifySubstitution( d_var, subs, rhs );\r
-  }else{\r
-    Assert( i==0 || !d_children.empty() );\r
-    for( std::map< TNode, SubstitutionIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){\r
-      Trace("sg-cconj-debug2") << "Try " << d_var << " -> " << it->first << " (" << i << "/" << numVars << ")" << std::endl;\r
-      subs[d_var] = it->first;\r
-      if( !it->second.notifySubstitutions( s, subs, rhs, numVars, i+1 ) ){\r
-        return false;\r
-      }\r
-    }\r
-    return true;\r
-  }\r
-}\r
-\r
-\r
-void TheoremIndex::addTheorem( std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs ){\r
-  if( lhs_v.empty() ){\r
-    if( std::find( d_terms.begin(), d_terms.end(), rhs )==d_terms.end() ){\r
-      d_terms.push_back( rhs );\r
-    }\r
-  }else{\r
-    unsigned index = lhs_v.size()-1;\r
-    if( lhs_arg[index]==lhs_v[index].getNumChildren() ){\r
-      lhs_v.pop_back();\r
-      lhs_arg.pop_back();\r
-      addTheorem( lhs_v, lhs_arg, rhs );\r
-    }else{\r
-      lhs_arg[index]++;\r
-      addTheoremNode( lhs_v[index][lhs_arg[index]-1], lhs_v, lhs_arg, rhs );\r
-    }\r
-  }\r
-}\r
-\r
-void TheoremIndex::addTheoremNode( TNode curr, std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs ){\r
-  Trace("thm-db-debug") << "Adding conjecture for subterm " << curr << "..." << std::endl;\r
-  if( curr.hasOperator() ){\r
-    lhs_v.push_back( curr );\r
-    lhs_arg.push_back( 0 );\r
-    d_children[curr.getOperator()].addTheorem( lhs_v, lhs_arg, rhs );\r
-  }else{\r
-    Assert( curr.getKind()==kind::BOUND_VARIABLE );\r
-    TypeNode tn = curr.getType();\r
-    Assert( d_var[tn].isNull() || d_var[tn]==curr );\r
-    d_var[tn] = curr;\r
-    d_children[curr].addTheorem( lhs_v, lhs_arg, rhs );\r
-  }\r
-}\r
-\r
-void TheoremIndex::getEquivalentTerms( std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,\r
-                                       std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,\r
-                                       std::vector< Node >& terms ) {\r
-  Trace("thm-db-debug") << "Get equivalent terms " << n_v.size() << " " << n_arg.size() << std::endl;\r
-  if( n_v.empty() ){\r
-    Trace("thm-db-debug") << "Number of terms : " << d_terms.size() << std::endl;\r
-    //apply substutitions to RHS's\r
-    for( unsigned i=0; i<d_terms.size(); i++ ){\r
-      Node n = d_terms[i].substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );\r
-      terms.push_back( n );\r
-    }\r
-  }else{\r
-    unsigned index = n_v.size()-1;\r
-    if( n_arg[index]==n_v[index].getNumChildren() ){\r
-      n_v.pop_back();\r
-      n_arg.pop_back();\r
-      getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );\r
-    }else{\r
-      n_arg[index]++;\r
-      getEquivalentTermsNode( n_v[index][n_arg[index]-1], n_v, n_arg, smap, vars, subs, terms );\r
-    }\r
-  }\r
-}\r
-\r
-void TheoremIndex::getEquivalentTermsNode( Node curr, std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,\r
-                                           std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,\r
-                                           std::vector< Node >& terms ) {\r
-  Trace("thm-db-debug") << "Get equivalent based on subterm " << curr << "..." << std::endl;\r
-  if( curr.hasOperator() ){\r
-    Trace("thm-db-debug") << "Check based on operator..." << std::endl;\r
-    std::map< TNode, TheoremIndex >::iterator it = d_children.find( curr.getOperator() );\r
-    if( it!=d_children.end() ){\r
-      n_v.push_back( curr );\r
-      n_arg.push_back( 0 );\r
-      it->second.getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );\r
-    }\r
-    Trace("thm-db-debug") << "...done check based on operator" << std::endl;\r
-  }\r
-  TypeNode tn = curr.getType();\r
-  std::map< TypeNode, TNode >::iterator itt = d_var.find( tn );\r
-  if( itt!=d_var.end() ){\r
-    Trace("thm-db-debug") << "Check for substitution with " << itt->second << "..." << std::endl;\r
-    Assert( curr.getType()==itt->second.getType() );\r
-    //add to substitution if possible\r
-    bool success = false;\r
-    std::map< TNode, TNode >::iterator it = smap.find( itt->second );\r
-    if( it==smap.end() ){\r
-      smap[itt->second] = curr;\r
-      vars.push_back( itt->second );\r
-      subs.push_back( curr );\r
-      success = true;\r
-    }else if( it->second==curr ){\r
-      success = true;\r
-    }else{\r
-      //also check modulo equality (in universal equality engine)\r
-    }\r
-    Trace("thm-db-debug") << "...check for substitution with " << itt->second << ", success = " << success << "." << std::endl;\r
-    if( success ){\r
-      d_children[itt->second].getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );\r
-    }\r
-  }\r
-}\r
-\r
-void TheoremIndex::debugPrint( const char * c, unsigned ind ) {\r
-  for( std::map< TNode, TheoremIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){\r
-    for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }\r
-    Trace(c) << it->first << std::endl;\r
-    it->second.debugPrint( c, ind+1 );\r
-  }\r
-  if( !d_terms.empty() ){\r
-    for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }\r
-    Trace(c) << "{";\r
-    for( unsigned i=0; i<d_terms.size(); i++ ){\r
-      Trace(c) << " " << d_terms[i];\r
-    }\r
-    Trace(c) << " }" << std::endl;\r
-  }\r
-  //if( !d_var.isNull() ){\r
-  //  for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }\r
-  //  Trace(c) << "var:" << d_var << std::endl;\r
-  //}\r
-}\r
-\r
-bool ConjectureGenerator::optReqDistinctVarPatterns() { return false; }\r
-bool ConjectureGenerator::optFilterUnknown() { return true; }  //may change\r
-int ConjectureGenerator::optFilterScoreThreshold() { return 1; }\r
-unsigned ConjectureGenerator::optFullCheckFrequency() { return 1; }\r
-\r
-bool ConjectureGenerator::optStatsOnly() { return false; }\r
-\r
-}\r
+/*********************                                                        */
+/*! \file conjecture_generator.cpp
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief conjecture generator class
+ **
+ **/
+
+#include "theory/quantifiers/conjecture_generator.h"
+#include "theory/theory_engine.h"
+#include "theory/quantifiers/options.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/quantifiers/trigger.h"
+#include "theory/quantifiers/first_order_model.h"
+
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+using namespace std;
+
+namespace CVC4 {
+
+struct sortConjectureScore {
+  std::vector< int > d_scores;
+  bool operator() (unsigned i, unsigned j) { return d_scores[i]>d_scores[j]; }
+};
+
+
+void OpArgIndex::addTerm( ConjectureGenerator * s, TNode n, unsigned index ){
+  if( index==n.getNumChildren() ){
+    Assert( n.hasOperator() );
+    if( std::find( d_ops.begin(), d_ops.end(), n.getOperator() )==d_ops.end() ){
+      d_ops.push_back( n.getOperator() );
+      d_op_terms.push_back( n );
+    }
+  }else{
+    d_child[s->getTermDatabase()->d_arg_reps[n][index]].addTerm( s, n, index+1 );
+  }
+}
+
+Node OpArgIndex::getGroundTerm( ConjectureGenerator * s, std::vector< TNode >& args ) {
+  if( d_ops.empty() ){
+    for( std::map< TNode, OpArgIndex >::iterator it = d_child.begin(); it != d_child.end(); ++it ){
+      std::map< TNode, Node >::iterator itf = s->d_ground_eqc_map.find( it->first );
+      if( itf!=s->d_ground_eqc_map.end() ){
+        args.push_back( itf->second );
+        Node n = it->second.getGroundTerm( s, args );
+        args.pop_back();
+        if( !n.isNull() ){
+          return n;
+        }
+      }
+    }
+    return Node::null();
+  }else{
+    std::vector< TNode > args2;
+    args2.push_back( d_ops[0] );
+    args2.insert( args2.end(), args.begin(), args.end() );
+    return NodeManager::currentNM()->mkNode( d_op_terms[0].getKind(), args2 );
+  }
+}
+
+void OpArgIndex::getGroundTerms( ConjectureGenerator * s, std::vector< TNode >& terms ) {
+  terms.insert( terms.end(), d_op_terms.begin(), d_op_terms.end() );
+  for( std::map< TNode, OpArgIndex >::iterator it = d_child.begin(); it != d_child.end(); ++it ){
+    if( s->isGroundEqc( it->first ) ){
+      it->second.getGroundTerms( s, terms );
+    }
+  }
+}
+
+
+
+ConjectureGenerator::ConjectureGenerator( QuantifiersEngine * qe, context::Context* c ) : QuantifiersModule( qe ),
+d_notify( *this ),
+d_uequalityEngine(d_notify, c, "ConjectureGenerator::ee", false),
+d_ee_conjectures( c ){
+  d_fullEffortCount = 0;
+  d_uequalityEngine.addFunctionKind( kind::APPLY_UF );
+  d_uequalityEngine.addFunctionKind( kind::APPLY_CONSTRUCTOR );
+
+}
+
+void ConjectureGenerator::eqNotifyNewClass( TNode t ){
+  Trace("thm-ee-debug") << "UEE : new equivalence class " << t << std::endl;
+  d_upendingAdds.push_back( t );
+}
+
+void ConjectureGenerator::eqNotifyPreMerge(TNode t1, TNode t2) {
+  //get maintained representatives
+  TNode rt1 = t1;
+  TNode rt2 = t2;
+  std::map< Node, EqcInfo* >::iterator it1 = d_eqc_info.find( t1 );
+  if( it1!=d_eqc_info.end() && !it1->second->d_rep.get().isNull() ){
+    rt1 = it1->second->d_rep.get();
+  }
+  std::map< Node, EqcInfo* >::iterator it2 = d_eqc_info.find( t2 );
+  if( it2!=d_eqc_info.end() && !it2->second->d_rep.get().isNull() ){
+    rt2 = it2->second->d_rep.get();
+  }
+  Trace("thm-ee-debug") << "UEE : equality holds : " << t1 << " == " << t2 << std::endl;
+  Trace("thm-ee-debug") << "      ureps : " << rt1 << " == " << rt2 << std::endl;
+  Trace("thm-ee-debug") << "      relevant : " << d_pattern_is_relevant[rt1] << " " << d_pattern_is_relevant[rt2] << std::endl;
+  Trace("thm-ee-debug") << "      normal : " << d_pattern_is_normal[rt1] << " " << d_pattern_is_normal[rt2] << std::endl;
+  Trace("thm-ee-debug") << "      size :   " << d_pattern_fun_sum[rt1] << " " << d_pattern_fun_sum[rt2] << std::endl;
+
+  if( isUniversalLessThan( rt2, rt1 ) ){
+    EqcInfo * ei;
+    if( it1==d_eqc_info.end() ){
+      ei = getOrMakeEqcInfo( t1, true );
+    }else{
+      ei = it1->second;
+    }
+    ei->d_rep = t2;
+  }
+}
+
+void ConjectureGenerator::eqNotifyPostMerge(TNode t1, TNode t2) {
+
+}
+
+void ConjectureGenerator::eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {
+  Trace("thm-ee-debug") << "UEE : disequality holds : " << t1 << " != " << t2 << std::endl;
+
+}
+
+
+ConjectureGenerator::EqcInfo::EqcInfo( context::Context* c ) : d_rep( c, Node::null() ){
+
+}
+
+ConjectureGenerator::EqcInfo* ConjectureGenerator::getOrMakeEqcInfo( TNode n, bool doMake ) {
+  //Assert( getUniversalRepresentative( n )==n );
+  std::map< Node, EqcInfo* >::iterator eqc_i = d_eqc_info.find( n );
+  if( eqc_i!=d_eqc_info.end() ){
+    return eqc_i->second;
+  }else if( doMake ){
+    EqcInfo* ei = new EqcInfo( d_quantEngine->getSatContext() );
+    d_eqc_info[n] = ei;
+    return ei;
+  }else{
+    return NULL;
+  }
+}
+
+void ConjectureGenerator::setUniversalRelevant( TNode n ) {
+  //add pattern information
+  registerPattern( n, n.getType() );
+  d_urelevant_terms[n] = true;
+  for( unsigned i=0; i<n.getNumChildren(); i++ ){
+    setUniversalRelevant( n[i] );
+  }
+}
+
+bool ConjectureGenerator::isUniversalLessThan( TNode rt1, TNode rt2 ) {
+  //prefer the one that is (normal, smaller) lexographically
+  Assert( d_pattern_is_relevant.find( rt1 )!=d_pattern_is_relevant.end() );
+  Assert( d_pattern_is_relevant.find( rt2 )!=d_pattern_is_relevant.end() );
+  Assert( d_pattern_is_normal.find( rt1 )!=d_pattern_is_normal.end() );
+  Assert( d_pattern_is_normal.find( rt2 )!=d_pattern_is_normal.end() );
+  Assert( d_pattern_fun_sum.find( rt1 )!=d_pattern_fun_sum.end() );
+  Assert( d_pattern_fun_sum.find( rt2 )!=d_pattern_fun_sum.end() );
+
+  if( d_pattern_is_relevant[rt1] && !d_pattern_is_relevant[rt2] ){
+    Trace("thm-ee-debug") << "UEE : LT due to relevant." << std::endl;
+    return true;
+  }else if( d_pattern_is_relevant[rt1]==d_pattern_is_relevant[rt2] ){
+    if( d_pattern_is_normal[rt1] && !d_pattern_is_normal[rt2] ){
+      Trace("thm-ee-debug") << "UEE : LT due to normal." << std::endl;
+      return true;
+    }else if( d_pattern_is_normal[rt1]==d_pattern_is_normal[rt2] ){
+      if( d_pattern_fun_sum[rt1]<d_pattern_fun_sum[rt2] ){
+        Trace("thm-ee-debug") << "UEE : LT due to size." << std::endl;
+        //decide which representative to use : based on size of the term
+        return true;
+      }else if( d_pattern_fun_sum[rt1]==d_pattern_fun_sum[rt2] ){
+        //same size : tie goes to term that has already been reported
+        return isReportedCanon( rt1 ) && !isReportedCanon( rt2 );
+      }
+    }
+  }
+  return false;
+}
+
+
+bool ConjectureGenerator::isReportedCanon( TNode n ) {
+  return std::find( d_ue_canon.begin(), d_ue_canon.end(), n )==d_ue_canon.end();
+}
+
+void ConjectureGenerator::markReportedCanon( TNode n ) {
+  if( !isReportedCanon( n ) ){
+    d_ue_canon.push_back( n );
+  }
+}
+
+bool ConjectureGenerator::areUniversalEqual( TNode n1, TNode n2 ) {
+  return n1==n2 || ( d_uequalityEngine.hasTerm( n1 ) && d_uequalityEngine.hasTerm( n2 ) && d_uequalityEngine.areEqual( n1, n2 ) );
+}
+
+bool ConjectureGenerator::areUniversalDisequal( TNode n1, TNode n2 ) {
+  return n1!=n2 && d_uequalityEngine.hasTerm( n1 ) && d_uequalityEngine.hasTerm( n2 ) && d_uequalityEngine.areDisequal( n1, n2, false );
+}
+
+TNode ConjectureGenerator::getUniversalRepresentative( TNode n, bool add ) {
+  if( add ){
+    if( d_urelevant_terms.find( n )==d_urelevant_terms.end() ){
+      setUniversalRelevant( n );
+      //add term to universal equality engine
+      d_uequalityEngine.addTerm( n );
+      // addding this term to equality engine will lead to a set of new terms (the new subterms of n)
+      // now, do instantiation-based merging for each of these terms
+      Trace("thm-ee-debug") << "Merge equivalence classes based on instantiations of terms..." << std::endl;
+      //merge all pending equalities
+      while( !d_upendingAdds.empty() ){
+        Trace("sg-pending") << "Add " << d_upendingAdds.size() << " pending terms..." << std::endl;
+        std::vector< Node > pending;
+        pending.insert( pending.end(), d_upendingAdds.begin(), d_upendingAdds.end() );
+        d_upendingAdds.clear();
+        for( unsigned i=0; i<pending.size(); i++ ){
+          Node t = pending[i];
+          TypeNode tn = t.getType();
+          Trace("thm-ee-add") << "UEE : Add universal term " << t << std::endl;
+          std::vector< Node > eq_terms;
+          //if occurs modulo equality at ground level, it is equivalent to representative of ground equality engine
+          TNode gt = getTermDatabase()->evaluateTerm( t );
+          if( !gt.isNull() && gt!=t ){
+            eq_terms.push_back( gt );
+          }
+          //get all equivalent terms based on theorem database
+          d_thm_index.getEquivalentTerms( t, eq_terms );
+          if( !eq_terms.empty() ){
+            Trace("thm-ee-add") << "UEE : Based on ground EE/theorem DB, it is equivalent to " << eq_terms.size() << " terms : " << std::endl;
+            //add equivalent terms as equalities to universal engine
+            for( unsigned i=0; i<eq_terms.size(); i++ ){
+              Trace("thm-ee-add") << "  " << eq_terms[i] << std::endl;
+              bool assertEq = false;
+              if( d_urelevant_terms.find( eq_terms[i] )!=d_urelevant_terms.end() ){
+                assertEq = true;
+              }else{
+                Assert( eq_terms[i].getType()==tn );
+                registerPattern( eq_terms[i], tn );
+                if( isUniversalLessThan( eq_terms[i], t ) || ( options::conjectureUeeIntro() && d_pattern_fun_sum[t]>=d_pattern_fun_sum[eq_terms[i]] ) ){
+                  setUniversalRelevant( eq_terms[i] );
+                  assertEq = true;
+                }
+              }
+              if( assertEq ){
+                Node exp;
+                d_uequalityEngine.assertEquality( t.eqNode( eq_terms[i] ), true, exp );
+              }else{
+                Trace("thm-ee-no-add") << "Do not add : " << t << " == " << eq_terms[i] << std::endl;
+              }
+            }
+          }else{
+            Trace("thm-ee-add") << "UEE : No equivalent terms." << std::endl;
+          }
+        }
+      }
+    }
+  }
+
+  if( d_uequalityEngine.hasTerm( n ) ){
+    Node r = d_uequalityEngine.getRepresentative( n );
+    EqcInfo * ei = getOrMakeEqcInfo( r );
+    if( ei && !ei->d_rep.get().isNull() ){
+      return ei->d_rep.get();
+    }else{
+      return r;
+    }
+  }else{
+    return n;
+  }
+}
+
+Node ConjectureGenerator::getFreeVar( TypeNode tn, unsigned i ) {
+  Assert( !tn.isNull() );
+  while( d_free_var[tn].size()<=i ){
+    std::stringstream oss;
+    oss << tn;
+    std::string typ_name = oss.str();
+    while( typ_name[0]=='(' ){
+      typ_name.erase( typ_name.begin() );
+    }
+    std::stringstream os;
+    os << typ_name[0] << i;
+    Node x = NodeManager::currentNM()->mkBoundVar( os.str().c_str(), tn );
+    d_free_var_num[x] = d_free_var[tn].size();
+    d_free_var[tn].push_back( x );
+  }
+  return d_free_var[tn][i];
+}
+
+
+
+Node ConjectureGenerator::getCanonicalTerm( TNode n, std::map< TypeNode, unsigned >& var_count, std::map< TNode, TNode >& subs ) {
+  if( n.getKind()==BOUND_VARIABLE ){
+    std::map< TNode, TNode >::iterator it = subs.find( n );
+    if( it==subs.end() ){
+      TypeNode tn = n.getType();
+      //allocate variable
+      unsigned vn = var_count[tn];
+      var_count[tn]++;
+      subs[n] = getFreeVar( tn, vn );
+      return subs[n];
+    }else{
+      return it->second;
+    }
+  }else{
+    std::vector< Node > children;
+    if( n.getKind()!=EQUAL ){
+      if( n.hasOperator() ){
+        TNode op = n.getOperator();
+        if( !d_tge.isRelevantFunc( op ) ){
+          return Node::null();
+        }
+        children.push_back( op );
+      }else{
+        return Node::null();
+      }
+    }
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      Node cn = getCanonicalTerm( n[i], var_count, subs );
+      if( cn.isNull() ){
+        return Node::null();
+      }else{
+        children.push_back( cn );
+      }
+    }
+    return NodeManager::currentNM()->mkNode( n.getKind(), children );
+  }
+}
+
+bool ConjectureGenerator::isHandledTerm( TNode n ){
+  return !n.getAttribute(NoMatchAttribute()) && inst::Trigger::isAtomicTrigger( n ) && ( n.getKind()!=APPLY_UF || n.getOperator().getKind()!=SKOLEM );
+}
+
+Node ConjectureGenerator::getGroundEqc( TNode r ) {
+  std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );
+  return it!=d_ground_eqc_map.end() ? it->second : Node::null();
+}
+
+bool ConjectureGenerator::isGroundEqc( TNode r ) {
+  return d_ground_eqc_map.find( r )!=d_ground_eqc_map.end();
+}
+
+bool ConjectureGenerator::isGroundTerm( TNode n ) {
+  return std::find( d_ground_terms.begin(), d_ground_terms.end(), n )!=d_ground_terms.end();
+}
+
+bool ConjectureGenerator::needsCheck( Theory::Effort e ) {
+  // synchonized with instantiation engine
+  return d_quantEngine->getInstWhenNeedsCheck( e );
+}
+
+bool ConjectureGenerator::hasEnumeratedUf( Node n ) {
+  if( options::conjectureGenGtEnum()>0 ){
+    std::map< Node, bool >::iterator it = d_uf_enum.find( n.getOperator() );
+    if( it==d_uf_enum.end() ){
+      d_uf_enum[n.getOperator()] = true;
+      std::vector< Node > lem;
+      getEnumeratePredUfTerm( n, options::conjectureGenGtEnum(), lem );
+      if( !lem.empty() ){
+        for( unsigned j=0; j<lem.size(); j++ ){
+          d_quantEngine->addLemma( lem[j], false );
+          d_hasAddedLemma = true;
+        }
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+void ConjectureGenerator::reset_round( Theory::Effort e ) {
+
+}
+
+void ConjectureGenerator::check( Theory::Effort e, unsigned quant_e ) {
+  if( quant_e==QuantifiersEngine::QEFFORT_STANDARD ){
+    d_fullEffortCount++;
+    if( d_fullEffortCount%optFullCheckFrequency()==0 ){
+      d_hasAddedLemma = false;
+      d_tge.d_cg = this;
+      double clSet = 0;
+      if( Trace.isOn("sg-engine") ){
+        clSet = double(clock())/double(CLOCKS_PER_SEC);
+        Trace("sg-engine") << "---Conjecture Engine Round, effort = " << e << "---" << std::endl;
+      }
+      eq::EqualityEngine * ee = getEqualityEngine();
+      d_conj_count = 0;
+
+      Trace("sg-proc") << "Get eq classes..." << std::endl;
+      d_op_arg_index.clear();
+      d_ground_eqc_map.clear();
+      d_bool_eqc[0] = Node::null();
+      d_bool_eqc[1] = Node::null();
+      std::vector< TNode > eqcs;
+      d_em.clear();
+      eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( ee );
+      while( !eqcs_i.isFinished() ){
+        TNode r = (*eqcs_i);
+        eqcs.push_back( r );
+        if( r.getType().isBoolean() ){
+          if( areEqual( r, getTermDatabase()->d_true ) ){
+            d_ground_eqc_map[r] = getTermDatabase()->d_true;
+            d_bool_eqc[0] = r;
+          }else if( areEqual( r, getTermDatabase()->d_false ) ){
+            d_ground_eqc_map[r] = getTermDatabase()->d_false;
+            d_bool_eqc[1] = r;
+          }
+        }
+        d_em[r] = eqcs.size();
+        eq::EqClassIterator ieqc_i = eq::EqClassIterator( r, ee );
+        while( !ieqc_i.isFinished() ){
+          TNode n = (*ieqc_i);
+          if( getTermDatabase()->hasTermCurrent( n ) ){
+            if( isHandledTerm( n ) ){
+              d_op_arg_index[r].addTerm( this, n );
+            }
+          }
+          ++ieqc_i;
+        }
+        ++eqcs_i;
+      }
+      Assert( !d_bool_eqc[0].isNull() );
+      Assert( !d_bool_eqc[1].isNull() );
+      d_urelevant_terms.clear();
+      Trace("sg-proc") << "...done get eq classes" << std::endl;
+
+      Trace("sg-proc") << "Determine ground EQC..." << std::endl;
+      bool success;
+      do{
+        success = false;
+        for( unsigned i=0; i<eqcs.size(); i++ ){
+          TNode r = eqcs[i];
+          if( d_ground_eqc_map.find( r )==d_ground_eqc_map.end() ){
+            std::vector< TNode > args;
+            Trace("sg-pat-debug") << "******* Get ground term for " << r << std::endl;
+            Node n;
+            if( getTermDatabase()->isInductionTerm( r ) ){
+              n = d_op_arg_index[r].getGroundTerm( this, args );
+            }else{
+              n = r;
+            }
+            if( !n.isNull() ){
+              Trace("sg-pat") << "Ground term for eqc " << r << " : " << std::endl;
+              Trace("sg-pat") << "   " << n << std::endl;
+              d_ground_eqc_map[r] = n;
+              success = true;
+            }else{
+              Trace("sg-pat-debug") << "...could not find ground term." << std::endl;
+            }
+          }
+        }
+      }while( success );
+      //also get ground terms
+      d_ground_terms.clear();
+      for( unsigned i=0; i<eqcs.size(); i++ ){
+        TNode r = eqcs[i];
+        d_op_arg_index[r].getGroundTerms( this, d_ground_terms );
+      }
+      Trace("sg-proc") << "...done determine ground EQC" << std::endl;
+
+      //debug printing
+      if( Trace.isOn("sg-gen-eqc") ){
+        for( unsigned i=0; i<eqcs.size(); i++ ){
+          TNode r = eqcs[i];
+          //print out members
+          bool firstTime = true;
+          bool isFalse = areEqual( r, getTermDatabase()->d_false );
+          eq::EqClassIterator eqc_i = eq::EqClassIterator( r, ee );
+          while( !eqc_i.isFinished() ){
+            TNode n = (*eqc_i);
+            if( getTermDatabase()->hasTermCurrent( n ) && !n.getAttribute(NoMatchAttribute()) && ( n.getKind()!=EQUAL || isFalse ) ){
+              if( firstTime ){
+                Trace("sg-gen-eqc") << "e" << d_em[r] << " : { " << std::endl;
+                firstTime = false;
+              }
+              if( n.hasOperator() ){
+                Trace("sg-gen-eqc") << "   (" << n.getOperator();
+                getTermDatabase()->computeArgReps( n );
+                for( unsigned i=0; i<getTermDatabase()->d_arg_reps[n].size(); i++ ){
+                  Trace("sg-gen-eqc") << " e" << d_em[getTermDatabase()->d_arg_reps[n][i]];
+                }
+                Trace("sg-gen-eqc") << ") :: " << n << std::endl;
+              }else{
+                Trace("sg-gen-eqc") << "   " << n << std::endl;
+              }
+            }
+            ++eqc_i;
+          }
+          if( !firstTime ){
+            Trace("sg-gen-eqc") << "}" << std::endl;
+            //print out ground term
+            std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );
+            if( it!=d_ground_eqc_map.end() ){
+              Trace("sg-gen-eqc") << "- Ground term : " << it->second << std::endl;
+            }
+          }
+        }
+      }
+
+      Trace("sg-proc") << "Compute relevant eqc..." << std::endl;
+      d_tge.d_relevant_eqc[0].clear();
+      d_tge.d_relevant_eqc[1].clear();
+      for( unsigned i=0; i<eqcs.size(); i++ ){
+        TNode r = eqcs[i];
+        std::map< TNode, Node >::iterator it = d_ground_eqc_map.find( r );
+        unsigned index = 1;
+        if( it==d_ground_eqc_map.end() ){
+          index = 0;
+        }
+        //based on unproven conjectures? TODO
+        d_tge.d_relevant_eqc[index].push_back( r );
+      }
+      Trace("sg-gen-tg-debug") << "Initial relevant eqc : ";
+      for( unsigned i=0; i<d_tge.d_relevant_eqc[0].size(); i++ ){
+        Trace("sg-gen-tg-debug") << "e" << d_em[d_tge.d_relevant_eqc[0][i]] << " ";
+      }
+      Trace("sg-gen-tg-debug") << std::endl;
+      Trace("sg-proc") << "...done compute relevant eqc" << std::endl;
+
+
+      Trace("sg-proc") << "Collect signature information..." << std::endl;
+      d_tge.collectSignatureInformation();
+      if( d_hasAddedLemma ){
+        Trace("sg-proc") << "...added enumeration lemmas." << std::endl;
+      }
+      Trace("sg-proc") << "...done collect signature information" << std::endl;
+
+
+
+      Trace("sg-proc") << "Build theorem index..." << std::endl;
+      d_ue_canon.clear();
+      d_thm_index.clear();
+      std::vector< Node > provenConj;
+      quantifiers::FirstOrderModel* m = d_quantEngine->getModel();
+      for( int i=0; i<m->getNumAssertedQuantifiers(); i++ ){
+        Node q = m->getAssertedQuantifier( i );
+        Trace("thm-db-debug") << "Is " << q << " a relevant theorem?" << std::endl;
+        Node conjEq;
+        if( q[1].getKind()==EQUAL ){
+          bool isSubsume = false;
+          bool inEe = false;
+          for( unsigned r=0; r<2; r++ ){
+            TNode nl = q[1][r==0 ? 0 : 1];
+            TNode nr = q[1][r==0 ? 1 : 0];
+            Node eq = nl.eqNode( nr );
+            if( r==1 || std::find( d_conjectures.begin(), d_conjectures.end(), q )==d_conjectures.end() ){
+              //must make it canonical
+              std::map< TypeNode, unsigned > var_count;
+              std::map< TNode, TNode > subs;
+              Trace("sg-proc-debug") << "get canonical " << eq << std::endl;
+              eq = getCanonicalTerm( eq, var_count, subs );
+            }
+            if( !eq.isNull() ){
+              if( r==0 ){
+                inEe = d_ee_conjectures.find( q[1] )!=d_ee_conjectures.end();
+                if( !inEe ){
+                  //add to universal equality engine
+                  Node nl = getUniversalRepresentative( eq[0], true );
+                  Node nr = getUniversalRepresentative( eq[1], true );
+                  if( areUniversalEqual( nl, nr ) ){
+                    isSubsume = true;
+                    //set inactive (will be ignored by other modules)
+                    d_quantEngine->getModel()->setQuantifierActive( q, false );
+                  }else{
+                    Node exp;
+                    d_ee_conjectures[q[1]] = true;
+                    d_uequalityEngine.assertEquality( nl.eqNode( nr ), true, exp );
+                  }
+                }
+                Trace("sg-conjecture") << "*** CONJECTURE : currently proven" << (isSubsume ? " and subsumed" : "");
+                Trace("sg-conjecture") << " : " << q[1] << std::endl;
+                provenConj.push_back( q );
+              }
+              if( !isSubsume ){
+                Trace("thm-db-debug") << "Adding theorem to database " << eq[0] << " == " << eq[1] << std::endl;
+                d_thm_index.addTheorem( eq[0], eq[1] );
+              }else{
+                break;
+              }
+            }else{
+              break;
+            }
+          }
+        }
+      }
+      //examine status of other conjectures
+      for( unsigned i=0; i<d_conjectures.size(); i++ ){
+        Node q = d_conjectures[i];
+        if( std::find( provenConj.begin(), provenConj.end(), q )==provenConj.end() ){
+          //check each skolem variable
+          bool disproven = true;
+          //std::vector< Node > sk;
+          //getTermDatabase()->getSkolemConstants( q, sk, true );
+          Trace("sg-conjecture") << "    CONJECTURE : ";
+          std::vector< Node > ce;
+          for( unsigned j=0; j<getTermDatabase()->d_skolem_constants[q].size(); j++ ){
+            TNode k = getTermDatabase()->d_skolem_constants[q][j];
+            TNode rk = getRepresentative( k );
+            std::map< TNode, Node >::iterator git = d_ground_eqc_map.find( rk );
+            //check if it is a ground term
+            if( git==d_ground_eqc_map.end() ){
+              Trace("sg-conjecture") << "ACTIVE : " << q;
+              if( Trace.isOn("sg-gen-eqc") ){
+                Trace("sg-conjecture") << " { ";
+                for( unsigned k=0; k<getTermDatabase()->d_skolem_constants[q].size(); k++ ){ Trace("sg-conjecture") << getTermDatabase()->d_skolem_constants[q][k] << ( j==k ? "*" : "" ) << " "; }
+                Trace("sg-conjecture") << "}";
+              }
+              Trace("sg-conjecture") << std::endl;
+              disproven = false;
+              break;
+            }else{
+              ce.push_back( git->second );
+            }
+          }
+          if( disproven ){
+            Trace("sg-conjecture") << "disproven : " << q << " : ";
+            for( unsigned i=0; i<ce.size(); i++ ){
+              Trace("sg-conjecture") << q[0][i] << " -> " << ce[i] << " ";
+            }
+            Trace("sg-conjecture") << std::endl;
+          }
+        }
+      }
+      Trace("thm-db") << "Theorem database is : " << std::endl;
+      d_thm_index.debugPrint( "thm-db" );
+      Trace("thm-db") << std::endl;
+      Trace("sg-proc") << "...done build theorem index" << std::endl;
+
+
+      //clear patterns
+      d_patterns.clear();
+      d_pattern_var_id.clear();
+      d_pattern_var_duplicate.clear();
+      d_pattern_is_normal.clear();
+      d_pattern_is_relevant.clear();
+      d_pattern_fun_id.clear();
+      d_pattern_fun_sum.clear();
+      d_rel_patterns.clear();
+      d_rel_pattern_var_sum.clear();
+      d_rel_pattern_typ_index.clear();
+      d_rel_pattern_subs_index.clear();
+
+      unsigned rel_term_count = 0;
+      std::map< TypeNode, unsigned > rt_var_max;
+      std::vector< TypeNode > rt_types;
+      std::map< TypeNode, std::map< int, std::vector< Node > > > conj_lhs;
+      unsigned addedLemmas = 0;
+      for( unsigned depth=1; depth<=3; depth++ ){
+        Trace("sg-proc") << "Generate relevant LHS at depth " << depth << "..." << std::endl;
+        Trace("sg-rel-term") << "Relevant terms of depth " << depth << " : " << std::endl;
+        //set up environment
+        d_tge.d_var_id.clear();
+        d_tge.d_var_limit.clear();
+        d_tge.reset( depth, true, TypeNode::null() );
+        while( d_tge.getNextTerm() ){
+          //construct term
+          Node nn = d_tge.getTerm();
+          if( !options::conjectureFilterCanonical() || considerTermCanon( nn, true ) ){
+            rel_term_count++;
+            Trace("sg-rel-term") << "*** Relevant term : ";
+            d_tge.debugPrint( "sg-rel-term", "sg-rel-term-debug2" );
+            Trace("sg-rel-term") << std::endl;
+
+            for( unsigned r=0; r<2; r++ ){
+              Trace("sg-rel-term-debug") << "...from equivalence classes (" << r << ") : ";
+              int index = d_tge.d_ccand_eqc[r].size()-1;
+              for( unsigned j=0; j<d_tge.d_ccand_eqc[r][index].size(); j++ ){
+                Trace("sg-rel-term-debug") << "e" << d_em[d_tge.d_ccand_eqc[r][index][j]] << " ";
+              }
+              Trace("sg-rel-term-debug") << std::endl;
+            }
+            TypeNode tnn = nn.getType();
+            Trace("sg-gen-tg-debug") << "...term is " << nn << std::endl;
+            conj_lhs[tnn][depth].push_back( nn );
+
+            //add information about pattern
+            Trace("sg-gen-tg-debug") << "Collect pattern information..." << std::endl;
+            Assert( std::find( d_rel_patterns[tnn].begin(), d_rel_patterns[tnn].end(), nn )==d_rel_patterns[tnn].end() );
+            d_rel_patterns[tnn].push_back( nn );
+            //build information concerning the variables in this pattern
+            unsigned sum = 0;
+            std::map< TypeNode, unsigned > typ_to_subs_index;
+            std::vector< TNode > gsubs_vars;
+            for( std::map< TypeNode, unsigned >::iterator it = d_tge.d_var_id.begin(); it != d_tge.d_var_id.end(); ++it ){
+              if( it->second>0 ){
+                typ_to_subs_index[it->first] = sum;
+                sum += it->second;
+                for( unsigned i=0; i<it->second; i++ ){
+                  gsubs_vars.push_back( getFreeVar( it->first, i ) );
+                }
+              }
+            }
+            d_rel_pattern_var_sum[nn] = sum;
+            //register the pattern
+            registerPattern( nn, tnn );
+            Assert( d_pattern_is_normal[nn] );
+            Trace("sg-gen-tg-debug") << "...done collect pattern information" << std::endl;
+
+            //record information about types
+            Trace("sg-gen-tg-debug") << "Collect type information..." << std::endl;
+            PatternTypIndex * pti = &d_rel_pattern_typ_index;
+            for( std::map< TypeNode, unsigned >::iterator it = d_tge.d_var_id.begin(); it != d_tge.d_var_id.end(); ++it ){
+              pti = &pti->d_children[it->first][it->second];
+              //record maximum
+              if( rt_var_max.find( it->first )==rt_var_max.end() || it->second>rt_var_max[it->first] ){
+                rt_var_max[it->first] = it->second;
+              }
+            }
+            if( std::find( rt_types.begin(), rt_types.end(), tnn )==rt_types.end() ){
+              rt_types.push_back( tnn );
+            }
+            pti->d_terms.push_back( nn );
+            Trace("sg-gen-tg-debug") << "...done collect type information" << std::endl;
+
+            Trace("sg-gen-tg-debug") << "Build substitutions for ground EQC..." << std::endl;
+            std::vector< TNode > gsubs_terms;
+            gsubs_terms.resize( gsubs_vars.size() );
+            int index = d_tge.d_ccand_eqc[1].size()-1;
+            for( unsigned j=0; j<d_tge.d_ccand_eqc[1][index].size(); j++ ){
+              TNode r = d_tge.d_ccand_eqc[1][index][j];
+              Trace("sg-rel-term-debug") << "  Matches for e" << d_em[r] << ", which is ground term " << d_ground_eqc_map[r] << ":" << std::endl;
+              std::map< TypeNode, std::map< unsigned, TNode > > subs;
+              std::map< TNode, bool > rev_subs;
+              //only get ground terms
+              unsigned mode = 2;
+              d_tge.resetMatching( r, mode );
+              while( d_tge.getNextMatch( r, subs, rev_subs ) ){
+                //we will be building substitutions
+                bool firstTime = true;
+                for( std::map< TypeNode, std::map< unsigned, TNode > >::iterator it = subs.begin(); it != subs.end(); ++it ){
+                  unsigned tindex = typ_to_subs_index[it->first];
+                  for( std::map< unsigned, TNode >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
+                    if( !firstTime ){
+                      Trace("sg-rel-term-debug") << ", ";
+                    }else{
+                      firstTime = false;
+                      Trace("sg-rel-term-debug") << "    ";
+                    }
+                    Trace("sg-rel-term-debug") << it->first << ":x" << it2->first << " -> " << it2->second;
+                    Assert( tindex+it2->first<gsubs_terms.size() );
+                    gsubs_terms[tindex+it2->first] = it2->second;
+                  }
+                }
+                Trace("sg-rel-term-debug") << std::endl;
+                d_rel_pattern_subs_index[nn].addSubstitution( r, gsubs_vars, gsubs_terms );
+              }
+            }
+            Trace("sg-gen-tg-debug") << "...done build substitutions for ground EQC" << std::endl;
+          }else{
+            Trace("sg-gen-tg-debug") << "> not canonical : " << nn << std::endl;
+          }
+        }
+        Trace("sg-proc") << "...done generate terms at depth " << depth << std::endl;
+        Trace("sg-stats") << "--------> Total LHS of depth " << depth << " : " << rel_term_count << std::endl;
+        //Trace("conjecture-count") << "Total LHS of depth " << depth << " : " << conj_lhs[depth].size() << std::endl;
+
+        /* test...
+        for( unsigned i=0; i<rt_types.size(); i++ ){
+          Trace("sg-term-enum") << "Term enumeration for " << rt_types[i] << " : " << std::endl;
+          Trace("sg-term-enum") << "Ground term : " << rt_types[i].mkGroundTerm() << std::endl;
+          for( unsigned j=0; j<150; j++ ){
+            Trace("sg-term-enum") << "  " << getEnumerateTerm( rt_types[i], j ) << std::endl;
+          }
+        }
+        */
+
+        //consider types from relevant terms
+        for( unsigned rdepth=0; rdepth<=depth; rdepth++ ){
+          //set up environment
+          d_tge.d_var_id.clear();
+          d_tge.d_var_limit.clear();
+          for( std::map< TypeNode, unsigned >::iterator it = rt_var_max.begin(); it != rt_var_max.end(); ++it ){
+            d_tge.d_var_id[ it->first ] = it->second;
+            d_tge.d_var_limit[ it->first ] = it->second;
+          }
+          std::random_shuffle( rt_types.begin(), rt_types.end() );
+          std::map< TypeNode, std::vector< Node > > conj_rhs;
+          for( unsigned i=0; i<rt_types.size(); i++ ){
+
+            Trace("sg-proc") << "Generate relevant RHS terms of type " << rt_types[i] << " at depth " << rdepth << "..." << std::endl;
+            d_tge.reset( rdepth, false, rt_types[i] );
+
+            while( d_tge.getNextTerm() ){
+              Node rhs = d_tge.getTerm();
+              if( considerTermCanon( rhs, false ) ){
+                Trace("sg-rel-prop") << "Relevant RHS : " << rhs << std::endl;
+                //register pattern
+                Assert( rhs.getType()==rt_types[i] );
+                registerPattern( rhs, rt_types[i] );
+                if( rdepth<depth ){
+                  //consider against all LHS at depth
+                  for( unsigned j=0; j<conj_lhs[rt_types[i]][depth].size(); j++ ){
+                    processCandidateConjecture( conj_lhs[rt_types[i]][depth][j], rhs, depth, rdepth );
+                  }
+                }else{
+                  conj_rhs[rt_types[i]].push_back( rhs );
+                }
+              }
+            }
+          }
+          flushWaitingConjectures( addedLemmas, depth, rdepth );
+          //consider against all LHS up to depth
+          if( rdepth==depth ){
+            for( unsigned lhs_depth = 1; lhs_depth<=depth; lhs_depth++ ){
+              if( (int)addedLemmas<options::conjectureGenPerRound() ){
+                Trace("sg-proc") << "Consider conjectures at depth (" << lhs_depth << ", " << rdepth << ")..." << std::endl;
+                for( std::map< TypeNode, std::vector< Node > >::iterator it = conj_rhs.begin(); it != conj_rhs.end(); ++it ){
+                  for( unsigned j=0; j<it->second.size(); j++ ){
+                    for( unsigned k=0; k<conj_lhs[it->first][lhs_depth].size(); k++ ){
+                      processCandidateConjecture( conj_lhs[it->first][lhs_depth][k], it->second[j], lhs_depth, rdepth );
+                    }
+                  }
+                }
+                flushWaitingConjectures( addedLemmas, lhs_depth, depth );
+              }
+            }
+          }
+          if( (int)addedLemmas>=options::conjectureGenPerRound() ){
+            break;
+          }
+        }
+        if( (int)addedLemmas>=options::conjectureGenPerRound() ){
+          break;
+        }
+      }
+      Trace("sg-stats") << "Total conjectures considered : " << d_conj_count << std::endl;
+      if( Trace.isOn("thm-ee") ){
+        Trace("thm-ee") << "Universal equality engine is : " << std::endl;
+        eq::EqClassesIterator ueqcs_i = eq::EqClassesIterator( &d_uequalityEngine );
+        while( !ueqcs_i.isFinished() ){
+          TNode r = (*ueqcs_i);
+          bool firstTime = true;
+          TNode rr = getUniversalRepresentative( r );
+          Trace("thm-ee") << "  " << rr;
+          Trace("thm-ee") << " : { ";
+          eq::EqClassIterator ueqc_i = eq::EqClassIterator( r, &d_uequalityEngine );
+          while( !ueqc_i.isFinished() ){
+            TNode n = (*ueqc_i);
+            if( rr!=n ){
+              if( firstTime ){
+                Trace("thm-ee") << std::endl;
+                firstTime = false;
+              }
+              Trace("thm-ee") << "    " << n << std::endl;
+            }
+            ++ueqc_i;
+          }
+          if( !firstTime ){ Trace("thm-ee") << "  "; }
+          Trace("thm-ee") << "}" << std::endl;
+          ++ueqcs_i;
+        }
+        Trace("thm-ee") << std::endl;
+      }
+      if( Trace.isOn("sg-engine") ){
+        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
+        Trace("sg-engine") << "Finished conjecture generator, time = " << (clSet2-clSet) << std::endl;
+      }
+    }
+  }
+}
+
+unsigned ConjectureGenerator::flushWaitingConjectures( unsigned& addedLemmas, int ldepth, int rdepth ) {
+  if( !d_waiting_conjectures_lhs.empty() ){
+    Trace("sg-proc") << "Generated " << d_waiting_conjectures_lhs.size() << " conjectures at depth " << ldepth << "/" << rdepth << "." << std::endl;
+    if( (int)addedLemmas<options::conjectureGenPerRound() ){
+      /*
+      std::vector< unsigned > indices;
+      for( unsigned i=0; i<d_waiting_conjectures_lhs.size(); i++ ){
+        indices.push_back( i );
+      }
+      bool doSort = false;
+      if( doSort ){
+        //sort them based on score
+        sortConjectureScore scs;
+        scs.d_scores.insert( scs.d_scores.begin(), d_waiting_conjectures_score.begin(), d_waiting_conjectures_score.end() );
+        std::sort( indices.begin(), indices.end(), scs );
+      }
+      //if( doSort && d_waiting_conjectures_score[indices[0]]<optFilterScoreThreshold() ){
+      */
+      unsigned prevCount = d_conj_count;
+      for( unsigned i=0; i<d_waiting_conjectures_lhs.size(); i++ ){
+        if( d_waiting_conjectures_score[i]>=optFilterScoreThreshold() ){
+          //we have determined a relevant subgoal
+          Node lhs = d_waiting_conjectures_lhs[i];
+          Node rhs = d_waiting_conjectures_rhs[i];
+          if( options::conjectureFilterCanonical() && ( getUniversalRepresentative( lhs )!=lhs || getUniversalRepresentative( rhs )!=rhs ) ){
+            //skip
+          }else{
+            Trace("sg-engine") << "*** Consider conjecture : " << lhs << " == " << rhs << std::endl;
+            Trace("sg-engine-debug") << "      score : " << d_waiting_conjectures_score[i] << std::endl;
+            if( optStatsOnly() ){
+              d_conj_count++;
+            }else{
+              std::vector< Node > bvs;
+              for( std::map< TypeNode, unsigned >::iterator it = d_pattern_var_id[lhs].begin(); it != d_pattern_var_id[lhs].end(); ++it ){
+                for( unsigned i=0; i<=it->second; i++ ){
+                  bvs.push_back( getFreeVar( it->first, i ) );
+                }
+              }
+              Node rsg;
+              if( !bvs.empty() ){
+                Node bvl = NodeManager::currentNM()->mkNode( BOUND_VAR_LIST, bvs );
+                rsg = NodeManager::currentNM()->mkNode( FORALL, bvl, lhs.eqNode( rhs ) );
+              }else{
+                rsg = lhs.eqNode( rhs );
+              }
+              rsg = Rewriter::rewrite( rsg );
+              d_conjectures.push_back( rsg );
+              d_eq_conjectures[lhs].push_back( rhs );
+              d_eq_conjectures[rhs].push_back( lhs );
+
+              Node lem = NodeManager::currentNM()->mkNode( OR, rsg.negate(), rsg );
+              d_quantEngine->addLemma( lem, false );
+              d_quantEngine->addRequirePhase( rsg, false );
+              addedLemmas++;
+              if( (int)addedLemmas>=options::conjectureGenPerRound() ){
+                break;
+              }
+            }
+          }
+        }
+      }
+      Trace("sg-proc") << "...have now added " << addedLemmas << " conjecture lemmas." << std::endl;
+      if( optStatsOnly() ){
+        Trace("sg-stats") << "Generated " << (d_conj_count-prevCount) << " conjectures at depth " << ldepth << "/" << rdepth << "." << std::endl;
+      }
+    }
+    d_waiting_conjectures_lhs.clear();
+    d_waiting_conjectures_rhs.clear();
+    d_waiting_conjectures_score.clear();
+    d_waiting_conjectures.clear();
+  }
+  return addedLemmas;
+}
+
+void ConjectureGenerator::registerQuantifier( Node q ) {
+
+}
+
+void ConjectureGenerator::assertNode( Node n ) {
+
+}
+
+bool ConjectureGenerator::considerTermCanon( Node ln, bool genRelevant ){
+  if( !ln.isNull() ){
+    //do not consider if it is non-canonical, and either:
+    //  (1) we are not generating relevant terms, or
+    //  (2) its canonical form is a generalization.
+    TNode lnr = getUniversalRepresentative( ln, true );
+    if( lnr==ln ){
+      markReportedCanon( ln );
+    }else if( !genRelevant || isGeneralization( lnr, ln ) ){
+      Trace("sg-gen-consider-term") << "Do not consider term, " << ln << " is not canonical representation (which is " << lnr << ")." << std::endl;
+      return false;
+    }
+  }
+  Trace("sg-gen-tg-debug") << "Will consider term canon " << ln << std::endl;
+  Trace("sg-gen-consider-term-debug") << std::endl;
+  return true;
+}
+
+unsigned ConjectureGenerator::collectFunctions( TNode opat, TNode pat, std::map< TNode, unsigned >& funcs,
+                                             std::map< TypeNode, unsigned >& mnvn, std::map< TypeNode, unsigned >& mxvn ){
+  if( pat.hasOperator() ){
+    funcs[pat.getOperator()]++;
+    if( !d_tge.isRelevantFunc( pat.getOperator() ) ){
+      d_pattern_is_relevant[opat] = false;
+    }
+    unsigned sum = 1;
+    for( unsigned i=0; i<pat.getNumChildren(); i++ ){
+      sum += collectFunctions( opat, pat[i], funcs, mnvn, mxvn );
+    }
+    return sum;
+  }else{
+    Assert( pat.getNumChildren()==0 );
+    funcs[pat]++;
+    //for variables
+    if( pat.getKind()==BOUND_VARIABLE ){
+      if( funcs[pat]>1 ){
+        //duplicate variable
+        d_pattern_var_duplicate[opat]++;
+      }else{
+        //check for max/min
+        TypeNode tn = pat.getType();
+        unsigned vn = d_free_var_num[pat];
+        std::map< TypeNode, unsigned >::iterator it = mnvn.find( tn );
+        if( it!=mnvn.end() ){
+          if( vn<it->second ){
+            d_pattern_is_normal[opat] = false;
+            mnvn[tn] = vn;
+          }else if( vn>mxvn[tn] ){
+            if( vn!=mxvn[tn]+1 ){
+              d_pattern_is_normal[opat] = false;
+            }
+            mxvn[tn] = vn;
+          }
+        }else{
+          //first variable of this type
+          mnvn[tn] = vn;
+          mxvn[tn] = vn;
+        }
+      }
+    }else{
+      d_pattern_is_relevant[opat] = false;
+    }
+    return 1;
+  }
+}
+
+void ConjectureGenerator::registerPattern( Node pat, TypeNode tpat ) {
+  if( std::find( d_patterns[tpat].begin(), d_patterns[tpat].end(), pat )==d_patterns[tpat].end() ){
+    d_patterns[TypeNode::null()].push_back( pat );
+    d_patterns[tpat].push_back( pat );
+
+    Assert( d_pattern_fun_id.find( pat )==d_pattern_fun_id.end() );
+    Assert( d_pattern_var_id.find( pat )==d_pattern_var_id.end() );
+
+    //collect functions
+    std::map< TypeNode, unsigned > mnvn;
+    d_pattern_fun_sum[pat] = collectFunctions( pat, pat, d_pattern_fun_id[pat], mnvn, d_pattern_var_id[pat] );
+    if( d_pattern_is_normal.find( pat )==d_pattern_is_normal.end() ){
+      d_pattern_is_normal[pat] = true;
+    }
+    if( d_pattern_is_relevant.find( pat )==d_pattern_is_relevant.end() ){
+      d_pattern_is_relevant[pat] = true;
+    }
+  }
+}
+
+bool ConjectureGenerator::isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs ) {
+  if( patg.getKind()==BOUND_VARIABLE ){
+    std::map< TNode, TNode >::iterator it = subs.find( patg );
+    if( it!=subs.end() ){
+      return it->second==pat;
+    }else{
+      subs[patg] = pat;
+      return true;
+    }
+  }else{
+    Assert( patg.hasOperator() );
+    if( !pat.hasOperator() || patg.getOperator()!=pat.getOperator() ){
+      return false;
+    }else{
+      Assert( patg.getNumChildren()==pat.getNumChildren() );
+      for( unsigned i=0; i<patg.getNumChildren(); i++ ){
+        if( !isGeneralization( patg[i], pat[i], subs ) ){
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+}
+
+int ConjectureGenerator::calculateGeneralizationDepth( TNode n, std::vector< TNode >& fv ) {
+  if( n.getKind()==BOUND_VARIABLE ){
+    if( std::find( fv.begin(), fv.end(), n )==fv.end() ){
+      fv.push_back( n );
+      return 0;
+    }else{
+      return 1;
+    }
+  }else{
+    int depth = 1;
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      depth += calculateGeneralizationDepth( n[i], fv );
+    }
+    return depth;
+  }
+}
+
+Node ConjectureGenerator::getPredicateForType( TypeNode tn ) {
+  std::map< TypeNode, Node >::iterator it = d_typ_pred.find( tn );
+  if( it==d_typ_pred.end() ){
+    TypeNode op_tn = NodeManager::currentNM()->mkFunctionType( tn, NodeManager::currentNM()->booleanType() );
+    Node op = NodeManager::currentNM()->mkSkolem( "PE", op_tn, "was created by conjecture ground term enumerator." );
+    d_typ_pred[tn] = op;
+    return op;
+  }else{
+    return it->second;
+  }
+}
+
+void ConjectureGenerator::getEnumerateUfTerm( Node n, unsigned num, std::vector< Node >& terms ) {
+  if( n.getNumChildren()>0 ){
+    std::vector< int > vec;
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      vec.push_back( 0 );
+    }
+    vec.pop_back();
+    int size_limit = 0;
+    int vec_sum = -1;
+    unsigned index = 0;
+    unsigned last_size = terms.size();
+    while( terms.size()<num ){
+      bool success = true;
+      if( vec_sum==-1 ){
+        vec_sum = 0;
+        vec.push_back( size_limit );
+      }else{
+        //see if we can iterate current
+        if( vec_sum<size_limit && !getTermDatabase()->getEnumerateTerm( n[index].getType(), vec[index]+1 ).isNull() ){
+          vec[index]++;
+          vec_sum++;
+          vec.push_back( size_limit - vec_sum );
+        }else{
+          vec_sum -= vec[index];
+          vec[index] = 0;
+          index++;
+          if( index==n.getNumChildren() ){
+            success = false;
+          }
+        }
+      }
+      if( success ){
+        if( vec.size()==n.getNumChildren() ){
+          Node lc = getTermDatabase()->getEnumerateTerm( n[vec.size()-1].getType(), vec[vec.size()-1] );
+          if( !lc.isNull() ){
+            for( unsigned i=0; i<vec.size(); i++ ){
+              Trace("sg-gt-enum-debug") << vec[i] << " ";
+            }
+            Trace("sg-gt-enum-debug") << " / " << size_limit << std::endl;
+            for( unsigned i=0; i<n.getNumChildren(); i++ ){
+              Trace("sg-gt-enum-debug") << n[i].getType() << " ";
+            }
+            Trace("sg-gt-enum-debug") << std::endl;
+            std::vector< Node > children;
+            children.push_back( n.getOperator() );
+            for( unsigned i=0; i<(vec.size()-1); i++ ){
+              Node nn = getTermDatabase()->getEnumerateTerm( n[i].getType(), vec[i] );
+              Assert( !nn.isNull() );
+              Assert( nn.getType()==n[i].getType() );
+              children.push_back( nn );
+            }
+            children.push_back( lc );
+            Node n = NodeManager::currentNM()->mkNode( APPLY_UF, children );
+            Trace("sg-gt-enum") << "Ground term enumerate : " << n << std::endl;
+            terms.push_back( n );
+          }
+          vec.pop_back();
+          index = 0;
+        }
+      }else{
+        if( terms.size()>last_size ){
+          last_size = terms.size();
+          size_limit++;
+          for( unsigned i=0; i<vec.size(); i++ ){
+            vec[i] = 0;
+          }
+          vec_sum = -1;
+        }else{
+          return;
+        }
+      }
+    }
+  }else{
+    terms.push_back( n );
+  }
+}
+
+void ConjectureGenerator::getEnumeratePredUfTerm( Node n, unsigned num, std::vector< Node >& terms ) {
+  std::vector< Node > uf_terms;
+  getEnumerateUfTerm( n, num, uf_terms );
+  Node p = getPredicateForType( n.getType() );
+  for( unsigned i=0; i<uf_terms.size(); i++ ){
+    terms.push_back( NodeManager::currentNM()->mkNode( APPLY_UF, p, uf_terms[i] ) );
+  }
+}
+
+void ConjectureGenerator::processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth ) {
+  int score = considerCandidateConjecture( lhs, rhs );
+  if( score>0 ){
+    Trace("sg-conjecture") << "* Candidate conjecture : " << lhs << " == " << rhs << std::endl;
+    Trace("sg-conjecture-debug") << "     LHS, RHS generalization depth : " << lhs_depth << ", " << rhs_depth << std::endl;
+    Trace("sg-conjecture-debug") << "     confirmed = " << d_subs_confirmCount << ", #witnesses range = " << d_subs_confirmWitnessRange.size() << "." << std::endl;
+    Trace("sg-conjecture-debug") << "     #witnesses for ";
+    bool firstTime = true;
+    for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){
+      if( !firstTime ){
+        Trace("sg-conjecture-debug") << ", ";
+      }
+      Trace("sg-conjecture-debug") << it->first << " : " << it->second.size();
+      //if( it->second.size()==1 ){
+      //  Trace("sg-conjecture-debug") << " (" << it->second[0] << ")";
+      //}
+      Trace("sg-conjecture-debug2") << " (";
+      for( unsigned j=0; j<it->second.size(); j++ ){
+        if( j>0 ){ Trace("sg-conjecture-debug2") << " "; }
+        Trace("sg-conjecture-debug2") << d_ground_eqc_map[it->second[j]];
+      }
+      Trace("sg-conjecture-debug2") << ")";
+      firstTime = false;
+    }
+    Trace("sg-conjecture-debug") << std::endl;
+    Trace("sg-conjecture-debug") << "     unknown = " << d_subs_unkCount << std::endl;
+    //Assert( getUniversalRepresentative( rhs )==rhs );
+    //Assert( getUniversalRepresentative( lhs )==lhs );
+    d_waiting_conjectures_lhs.push_back( lhs );
+    d_waiting_conjectures_rhs.push_back( rhs );
+    d_waiting_conjectures_score.push_back( score );
+    d_waiting_conjectures[lhs].push_back( rhs );
+    d_waiting_conjectures[rhs].push_back( lhs );
+  }
+}
+
+int ConjectureGenerator::considerCandidateConjecture( TNode lhs, TNode rhs ) {
+  Assert( lhs.getType()==rhs.getType() );
+
+  Trace("sg-cconj-debug") << "Consider candidate conjecture : " << lhs << " == " << rhs << "?" << std::endl;
+  if( lhs==rhs ){
+    Trace("sg-cconj-debug") << "  -> trivial." << std::endl;
+    return -1;
+  }else{
+    if( lhs.getKind()==APPLY_CONSTRUCTOR && rhs.getKind()==APPLY_CONSTRUCTOR ){
+      Trace("sg-cconj-debug") << "  -> irrelevant by syntactic analysis." << std::endl;
+      return -1;
+    }
+    //variables of LHS must subsume variables of RHS
+    for( std::map< TypeNode, unsigned >::iterator it = d_pattern_var_id[rhs].begin(); it != d_pattern_var_id[rhs].end(); ++it ){
+      std::map< TypeNode, unsigned >::iterator itl = d_pattern_var_id[lhs].find( it->first );
+      if( itl!=d_pattern_var_id[lhs].end() ){
+        if( itl->second<it->second ){
+          Trace("sg-cconj-debug") << "  -> variables of sort " << it->first << " are not subsumed." << std::endl;
+          return -1;
+        }else{
+          Trace("sg-cconj-debug2") << "  variables of sort " << it->first << " are : " << itl->second << " vs " << it->second << std::endl;
+        }
+      }else{
+        Trace("sg-cconj-debug") << "  -> has no variables of sort " << it->first << "." << std::endl;
+        return -1;
+      }
+    }
+
+    //currently active conjecture?
+    std::map< Node, std::vector< Node > >::iterator iteq = d_eq_conjectures.find( lhs );
+    if( iteq!=d_eq_conjectures.end() ){
+      if( std::find( iteq->second.begin(), iteq->second.end(), rhs )!=iteq->second.end() ){
+        Trace("sg-cconj-debug") << "  -> this conjecture is already active." << std::endl;
+        return -1;
+      }
+    }
+    //current a waiting conjecture?
+    std::map< Node, std::vector< Node > >::iterator itw = d_waiting_conjectures.find( lhs );
+    if( itw!=d_waiting_conjectures.end() ){
+      if( std::find( itw->second.begin(), itw->second.end(), rhs )!=itw->second.end() ){
+        Trace("sg-cconj-debug") << "  -> already are considering this conjecture." << std::endl;
+        return -1;
+      }
+    }
+    //check if canonical representation (should be, but for efficiency this is not guarenteed)
+    //if( options::conjectureFilterCanonical() && ( getUniversalRepresentative( lhs )!=lhs || getUniversalRepresentative( rhs )!=rhs ) ){
+    //  Trace("sg-cconj") << "  -> after processing, not canonical." << std::endl;
+    //  return -1;
+    //}
+
+    int score;
+    bool scoreSet = false;
+
+    Trace("sg-cconj") << "Consider possible candidate conjecture : " << lhs << " == " << rhs << "?" << std::endl;
+    //find witness for counterexample, if possible
+    if( options::conjectureFilterModel() ){
+      Assert( d_rel_pattern_var_sum.find( lhs )!=d_rel_pattern_var_sum.end() );
+      Trace("sg-cconj-debug") << "Notify substitutions over " << d_rel_pattern_var_sum[lhs] << " variables." << std::endl;
+      std::map< TNode, TNode > subs;
+      d_subs_confirmCount = 0;
+      d_subs_confirmWitnessRange.clear();
+      d_subs_confirmWitnessDomain.clear();
+      d_subs_unkCount = 0;
+      if( !d_rel_pattern_subs_index[lhs].notifySubstitutions( this, subs, rhs, d_rel_pattern_var_sum[lhs] ) ){
+        Trace("sg-cconj") << "  -> found witness that falsifies the conjecture." << std::endl;
+        return -1;
+      }
+      //score is the minimum number of distinct substitutions for a variable
+      for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){
+        int num = (int)it->second.size();
+        if( !scoreSet || num<score ){
+          score = num;
+          scoreSet = true;
+        }
+      }
+      if( !scoreSet ){
+        score = 0;
+      }
+      Trace("sg-cconj") << "     confirmed = " << d_subs_confirmCount << ", #witnesses range = " << d_subs_confirmWitnessRange.size() << "." << std::endl;
+      for( std::map< TNode, std::vector< TNode > >::iterator it = d_subs_confirmWitnessDomain.begin(); it != d_subs_confirmWitnessDomain.end(); ++it ){
+        Trace("sg-cconj") << "     #witnesses for " << it->first << " : " << it->second.size() << std::endl;
+      }
+    }else{
+      score = 1;
+    }
+
+    Trace("sg-cconj") << "  -> SUCCESS." << std::endl;
+    Trace("sg-cconj") << "     score : " << score << std::endl;
+
+    return score;
+  }
+}
+
+bool ConjectureGenerator::notifySubstitution( TNode glhs, std::map< TNode, TNode >& subs, TNode rhs ) {
+  if( Trace.isOn("sg-cconj-debug") ){
+    Trace("sg-cconj-debug") << "Ground eqc for LHS : " << glhs << ", based on substituion: " << std::endl;
+    for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){
+      Assert( getRepresentative( it->second )==it->second );
+      Trace("sg-cconj-debug") << "  " << it->first << " -> " << it->second << std::endl;
+    }
+  }
+  Trace("sg-cconj-debug") << "Evaluate RHS : : " << rhs << std::endl;
+  //get the representative of rhs with substitution subs
+  TNode grhs = getTermDatabase()->evaluateTerm( rhs, subs, true );
+  Trace("sg-cconj-debug") << "...done evaluating term, got : " << grhs << std::endl;
+  if( !grhs.isNull() ){
+    if( glhs!=grhs ){
+      Trace("sg-cconj-debug") << "Ground eqc for RHS : " << grhs << std::endl;
+      //check based on ground terms
+      std::map< TNode, Node >::iterator itl = d_ground_eqc_map.find( glhs );
+      if( itl!=d_ground_eqc_map.end() ){
+        std::map< TNode, Node >::iterator itr = d_ground_eqc_map.find( grhs );
+        if( itr!=d_ground_eqc_map.end() ){
+          Trace("sg-cconj-debug") << "We have ground terms " << itl->second << " and " << itr->second << "." << std::endl;
+          if( itl->second.isConst() && itr->second.isConst() ){
+            Trace("sg-cconj-debug") << "...disequal constants." << std::endl;
+            Trace("sg-cconj-witness") << "  Witness of falsification : " << itl->second << " != " << itr->second << ", substutition is : " << std::endl;
+            for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){
+              Trace("sg-cconj-witness") << "    " << it->first << " -> " << it->second << std::endl;
+            }
+            return false;
+          }
+        }
+      }
+    }
+    Trace("sg-cconj-debug") << "RHS is identical." << std::endl;
+    bool isGroundSubs = true;
+    for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){
+      std::map< TNode, Node >::iterator git = d_ground_eqc_map.find( it->second );
+      if( git==d_ground_eqc_map.end() ){
+        isGroundSubs = false;
+        break;
+      }
+    }
+    if( isGroundSubs ){
+      if( glhs==grhs ){
+        Trace("sg-cconj-witness") << "  Witnessed " << glhs << " == " << grhs << ", substutition is : " << std::endl;
+        for( std::map< TNode, TNode >::iterator it = subs.begin(); it != subs.end(); ++it ){
+          Trace("sg-cconj-witness") << "    " << it->first << " -> " << it->second << std::endl;
+          if( std::find( d_subs_confirmWitnessDomain[it->first].begin(), d_subs_confirmWitnessDomain[it->first].end(), it->second )==d_subs_confirmWitnessDomain[it->first].end() ){
+            d_subs_confirmWitnessDomain[it->first].push_back( it->second );
+          }
+        }
+        d_subs_confirmCount++;
+        if( std::find( d_subs_confirmWitnessRange.begin(), d_subs_confirmWitnessRange.end(), glhs )==d_subs_confirmWitnessRange.end() ){
+          d_subs_confirmWitnessRange.push_back( glhs );
+        }
+      }else{
+        if( optFilterUnknown() ){
+          Trace("sg-cconj-debug") << "...ground substitution giving terms that are neither equal nor disequal." << std::endl;
+          return false;
+        }
+      }
+    }
+  }else{
+    Trace("sg-cconj-debug") << "(could not ground eqc for RHS)." << std::endl;
+  }
+  return true;
+}
+
+
+
+
+
+
+void TermGenerator::reset( TermGenEnv * s, TypeNode tn ) {
+  Assert( d_children.empty() );
+  d_typ = tn;
+  d_status = 0;
+  d_status_num = 0;
+  d_children.clear();
+  Trace("sg-gen-tg-debug2") << "...add to context " << this << std::endl;
+  d_id = s->d_tg_id;
+  s->changeContext( true );
+}
+
+bool TermGenerator::getNextTerm( TermGenEnv * s, unsigned depth ) {
+  if( Trace.isOn("sg-gen-tg-debug2") ){
+    Trace("sg-gen-tg-debug2") << this << " getNextTerm depth " << depth << " : status = " << d_status << ", num = " << d_status_num;
+    if( d_status==5 ){
+      TNode f = s->getTgFunc( d_typ, d_status_num );
+      Trace("sg-gen-tg-debug2") << ", f = " << f;
+      Trace("sg-gen-tg-debug2") << ", #args = " << s->d_func_args[f].size();
+      Trace("sg-gen-tg-debug2") << ", childNum = " << d_status_child_num;
+      Trace("sg-gen-tg-debug2") << ", #children = " << d_children.size();
+    }
+    Trace("sg-gen-tg-debug2") << std::endl;
+  }
+
+  if( d_status==0 ){
+    d_status++;
+    if( !d_typ.isNull() ){
+      if( s->allowVar( d_typ ) ){
+        //allocate variable
+        d_status_num = s->d_var_id[d_typ];
+        s->addVar( d_typ );
+        Trace("sg-gen-tg-debug2") << this << " ...return unique var #" << d_status_num << std::endl;
+        return s->considerCurrentTerm() ? true : getNextTerm( s, depth );
+      }else{
+        //check allocating new variable
+        d_status++;
+        d_status_num = -1;
+        if( s->d_gen_relevant_terms ){
+          s->d_tg_gdepth++;
+        }
+        return getNextTerm( s, depth );
+      }
+    }else{
+      d_status = 4;
+      d_status_num = -1;
+      return getNextTerm( s, depth );
+    }
+  }else if( d_status==2 ){
+    //cleanup previous information
+    //if( d_status_num>=0 ){
+    //  s->d_var_eq_tg[d_status_num].pop_back();
+    //}
+    //check if there is another variable
+    if( (d_status_num+1)<(int)s->getNumTgVars( d_typ ) ){
+      d_status_num++;
+      //we have equated two variables
+      //s->d_var_eq_tg[d_status_num].push_back( d_id );
+      Trace("sg-gen-tg-debug2") << this << "...consider other var #" << d_status_num << std::endl;
+      return s->considerCurrentTerm() ? true : getNextTerm( s, depth );
+    }else{
+      if( s->d_gen_relevant_terms ){
+        s->d_tg_gdepth--;
+      }
+      d_status++;
+      return getNextTerm( s, depth );
+    }
+  }else if( d_status==4 ){
+    d_status++;
+    if( depth>0 && (d_status_num+1)<(int)s->getNumTgFuncs( d_typ ) ){
+      d_status_num++;
+      d_status_child_num = 0;
+      Trace("sg-gen-tg-debug2") << this << "...consider function " << s->getTgFunc( d_typ, d_status_num ) << std::endl;
+      s->d_tg_gdepth++;
+      if( !s->considerCurrentTerm() ){
+        s->d_tg_gdepth--;
+        //don't consider this function
+        d_status--;
+      }else{
+        //we have decided on a function application
+      }
+      return getNextTerm( s, depth );
+    }else{
+      //do not choose function applications at depth 0
+      d_status++;
+      return getNextTerm( s, depth );
+    }
+  }else if( d_status==5 ){
+    //iterating over arguments
+    TNode f = s->getTgFunc( d_typ, d_status_num );
+    if( d_status_child_num<0 ){
+      //no more arguments
+      s->d_tg_gdepth--;
+      d_status--;
+      return getNextTerm( s, depth );
+    }else if( d_status_child_num==(int)s->d_func_args[f].size() ){
+      d_status_child_num--;
+      return s->considerCurrentTermCanon( d_id ) ? true : getNextTerm( s, depth );
+      //return true;
+    }else{
+      Assert( d_status_child_num<(int)s->d_func_args[f].size() );
+      if( d_status_child_num==(int)d_children.size() ){
+        d_children.push_back( s->d_tg_id );
+        Assert( s->d_tg_alloc.find( s->d_tg_id )==s->d_tg_alloc.end() );
+        s->d_tg_alloc[d_children[d_status_child_num]].reset( s, s->d_func_args[f][d_status_child_num] );
+        return getNextTerm( s, depth );
+      }else{
+        Assert( d_status_child_num+1==(int)d_children.size() );
+        if( s->d_tg_alloc[d_children[d_status_child_num]].getNextTerm( s, depth-1 ) ){
+          d_status_child_num++;
+          return getNextTerm( s, depth );
+        }else{
+          d_children.pop_back();
+          d_status_child_num--;
+          return getNextTerm( s, depth );
+        }
+      }
+    }
+  }else if( d_status==1 || d_status==3 ){
+    if( d_status==1 ){
+      s->removeVar( d_typ );
+      Assert( d_status_num==(int)s->d_var_id[d_typ] );
+      //check if there is only one feasible equivalence class.  if so, don't make pattern any more specific.
+      //unsigned i = s->d_ccand_eqc[0].size()-1;
+      //if( s->d_ccand_eqc[0][i].size()==1 && s->d_ccand_eqc[1][i].empty() ){
+      //  d_status = 6;
+      //  return getNextTerm( s, depth );
+      //}
+      s->d_tg_gdepth++;
+    }
+    d_status++;
+    d_status_num = -1;
+    return getNextTerm( s, depth );
+  }else{
+    //clean up
+    Assert( d_children.empty() );
+    Trace("sg-gen-tg-debug2") << "...remove from context " << this << std::endl;
+    s->changeContext( false );
+    Assert( d_id==s->d_tg_id );
+    return false;
+  }
+}
+
+void TermGenerator::resetMatching( TermGenEnv * s, TNode eqc, unsigned mode ) {
+  d_match_status = 0;
+  d_match_status_child_num = 0;
+  d_match_children.clear();
+  d_match_children_end.clear();
+  d_match_mode = mode;
+  //if this term generalizes, it must generalize a non-ground term
+  //if( (d_match_mode & ( 1 << 2 ))!=0 && s->isGroundEqc( eqc ) && d_status==5 ){
+  //  d_match_status = -1;
+  //}
+}
+
+bool TermGenerator::getNextMatch( TermGenEnv * s, TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs ) {
+  if( d_match_status<0 ){
+    return false;
+  }
+  if( Trace.isOn("sg-gen-tg-match") ){
+    Trace("sg-gen-tg-match") << "Matching ";
+    debugPrint( s, "sg-gen-tg-match", "sg-gen-tg-match" );
+    Trace("sg-gen-tg-match") << " with eqc e" << s->d_cg->d_em[eqc] << "..." << std::endl;
+    Trace("sg-gen-tg-match") << "   mstatus = " << d_match_status;
+    if( d_status==5 ){
+      TNode f = s->getTgFunc( d_typ, d_status_num );
+      Trace("sg-gen-tg-debug2") << ", f = " << f;
+      Trace("sg-gen-tg-debug2") << ", #args = " << s->d_func_args[f].size();
+      Trace("sg-gen-tg-debug2") << ", mchildNum = " << d_match_status_child_num;
+      Trace("sg-gen-tg-debug2") << ", #mchildren = " << d_match_children.size();
+    }
+    Trace("sg-gen-tg-debug2") << ", current substitution : {";
+    for( std::map< TypeNode, std::map< unsigned, TNode > >::iterator itt = subs.begin(); itt != subs.end(); ++itt ){
+      for( std::map< unsigned, TNode >::iterator it = itt->second.begin(); it != itt->second.end(); ++it ){
+        Trace("sg-gen-tg-debug2")  << " " << it->first << " -> e" << s->d_cg->d_em[it->second];
+      }
+    }
+    Trace("sg-gen-tg-debug2") << " } " << std::endl;
+  }
+  if( d_status==1 ){
+    //a variable
+    if( d_match_status==0 ){
+      d_match_status++;
+      if( (d_match_mode & ( 1 << 1 ))!=0 ){
+        //only ground terms
+        if( !s->isGroundEqc( eqc ) ){
+          return false;
+        }
+      }else if( (d_match_mode & ( 1 << 2 ))!=0 ){
+        //only non-ground terms
+        //if( s->isGroundEqc( eqc ) ){
+        //  return false;
+        //}
+      }
+      //store the match : restricted if match_mode.0 = 1
+      if( (d_match_mode & ( 1 << 0 ))!=0 ){
+        std::map< TNode, bool >::iterator it = rev_subs.find( eqc );
+        if( it==rev_subs.end() ){
+          rev_subs[eqc] = true;
+        }else{
+          return false;
+        }
+      }
+      Assert( subs[d_typ].find( d_status_num )==subs[d_typ].end() );
+      subs[d_typ][d_status_num] = eqc;
+      return true;
+    }else{
+      //clean up
+      subs[d_typ].erase( d_status_num );
+      if( (d_match_mode & ( 1 << 0 ))!=0 ){
+        rev_subs.erase( eqc );
+      }
+      return false;
+    }
+  }else if( d_status==2 ){
+    if( d_match_status==0 ){
+      d_match_status++;
+      Assert( d_status_num<(int)s->getNumTgVars( d_typ ) );
+      std::map< unsigned, TNode >::iterator it = subs[d_typ].find( d_status_num );
+      Assert( it!=subs[d_typ].end() );
+      return it->second==eqc;
+    }else{
+      return false;
+    }
+  }else if( d_status==5 ){
+    //Assert( d_match_children.size()<=d_children.size() );
+    //enumerating over f-applications in eqc
+    if( d_match_status_child_num<0 ){
+      return false;
+    }else if( d_match_status==0 ){
+      //set up next binding
+      if( d_match_status_child_num==(int)d_match_children.size() ){
+        if( d_match_status_child_num==0 ){
+          //initial binding
+          TNode f = s->getTgFunc( d_typ, d_status_num );
+          std::map< TNode, TermArgTrie >::iterator it = s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.find( eqc );
+          if( it!=s->getTermDatabase()->d_func_map_eqc_trie[f].d_data.end() ){
+            d_match_children.push_back( it->second.d_data.begin() );
+            d_match_children_end.push_back( it->second.d_data.end() );
+          }else{
+            d_match_status++;
+            d_match_status_child_num--;
+            return getNextMatch( s, eqc, subs, rev_subs );
+          }
+        }else{
+          d_match_children.push_back( d_match_children[d_match_status_child_num-1]->second.d_data.begin() );
+          d_match_children_end.push_back( d_match_children[d_match_status_child_num-1]->second.d_data.end() );
+        }
+      }
+      d_match_status++;
+      Assert( d_match_status_child_num+1==(int)d_match_children.size() );
+      if( d_match_children[d_match_status_child_num]==d_match_children_end[d_match_status_child_num] ){
+        //no more arguments to bind
+        d_match_children.pop_back();
+        d_match_children_end.pop_back();
+        d_match_status_child_num--;
+        return getNextMatch( s, eqc, subs, rev_subs );
+      }else{
+        if( d_match_status_child_num==(int)d_children.size() ){
+          //successfully matched all children
+          d_match_children.pop_back();
+          d_match_children_end.pop_back();
+          d_match_status_child_num--;
+          return true;//return d_match_children[d_match_status]!=d_match_children_end[d_match_status];
+        }else{
+          //do next binding
+          s->d_tg_alloc[d_children[d_match_status_child_num]].resetMatching( s, d_match_children[d_match_status_child_num]->first, d_match_mode );
+          return getNextMatch( s, eqc, subs, rev_subs );
+        }
+      }
+    }else{
+      Assert( d_match_status==1 );
+      Assert( d_match_status_child_num+1==(int)d_match_children.size() );
+      Assert( d_match_children[d_match_status_child_num]!=d_match_children_end[d_match_status_child_num] );
+      d_match_status--;
+      if( s->d_tg_alloc[d_children[d_match_status_child_num]].getNextMatch( s, d_match_children[d_match_status_child_num]->first, subs, rev_subs ) ){
+        d_match_status_child_num++;
+        return getNextMatch( s, eqc, subs, rev_subs );
+      }else{
+        //iterate
+        d_match_children[d_match_status_child_num]++;
+        return getNextMatch( s, eqc, subs, rev_subs );
+      }
+    }
+  }
+  Assert( false );
+  return false;
+}
+
+unsigned TermGenerator::getDepth( TermGenEnv * s ) {
+  if( d_status==5 ){
+    unsigned maxd = 0;
+    for( unsigned i=0; i<d_children.size(); i++ ){
+      unsigned d = s->d_tg_alloc[d_children[i]].getDepth( s );
+      if( d>maxd ){
+        maxd = d;
+      }
+    }
+    return 1+maxd;
+  }else{
+    return 0;
+  }
+}
+
+unsigned TermGenerator::calculateGeneralizationDepth( TermGenEnv * s, std::map< TypeNode, std::vector< int > >& fvs ) {
+  if( d_status==5 ){
+    unsigned sum = 1;
+    for( unsigned i=0; i<d_children.size(); i++ ){
+      sum += s->d_tg_alloc[d_children[i]].calculateGeneralizationDepth( s, fvs );
+    }
+    return sum;
+  }else{
+    Assert( d_status==2 || d_status==1 );
+    std::map< TypeNode, std::vector< int > >::iterator it = fvs.find( d_typ );
+    if( it!=fvs.end() ){
+      if( std::find( it->second.begin(), it->second.end(), d_status_num )!=it->second.end() ){
+        return 1;
+      }
+    }
+    fvs[d_typ].push_back( d_status_num );
+    return 0;
+  }
+}
+
+unsigned TermGenerator::getGeneralizationDepth( TermGenEnv * s ) {
+  //if( s->d_gen_relevant_terms ){
+  //  return s->d_tg_gdepth;
+  //}else{
+    std::map< TypeNode, std::vector< int > > fvs;
+    return calculateGeneralizationDepth( s, fvs );
+  //}
+}
+
+Node TermGenerator::getTerm( TermGenEnv * s ) {
+  if( d_status==1 || d_status==2 ){
+    Assert( !d_typ.isNull() );
+    return s->getFreeVar( d_typ, d_status_num );
+  }else if( d_status==5 ){
+    Node f = s->getTgFunc( d_typ, d_status_num );
+    if( d_children.size()==s->d_func_args[f].size() ){
+      std::vector< Node > children;
+      if( s->d_tg_func_param[f] ){
+        children.push_back( f );
+      }
+      for( unsigned i=0; i<d_children.size(); i++ ){
+        Node nc = s->d_tg_alloc[d_children[i]].getTerm( s );
+        if( nc.isNull() ){
+          return Node::null();
+        }else{
+          //Assert( nc.getType()==s->d_func_args[f][i] );
+          children.push_back( nc );
+        }
+      }
+      return NodeManager::currentNM()->mkNode( s->d_func_kind[f], children );
+    }
+  }else{
+    Assert( false );
+  }
+  return Node::null();
+}
+
+void TermGenerator::debugPrint( TermGenEnv * s, const char * c, const char * cd ) {
+  Trace(cd) << "[*" << d_id << "," << d_status << "]:";
+  if( d_status==1 || d_status==2 ){
+    Trace(c) << s->getFreeVar( d_typ, d_status_num );
+  }else if( d_status==5 ){
+    TNode f = s->getTgFunc( d_typ, d_status_num );
+    Trace(c) << "(" << f;
+    for( unsigned i=0; i<d_children.size(); i++ ){
+      Trace(c) << " ";
+       s->d_tg_alloc[d_children[i]].debugPrint( s, c, cd );
+    }
+    if( d_children.size()<s->d_func_args[f].size() ){
+      Trace(c) << " ...";
+    }
+    Trace(c) << ")";
+  }else{
+    Trace(c) << "???";
+  }
+}
+
+void TermGenEnv::collectSignatureInformation() {
+  d_typ_tg_funcs.clear();
+  d_funcs.clear();
+  d_func_kind.clear();
+  d_func_args.clear();
+  TypeNode tnull;
+  for( std::map< Node, TermArgTrie >::iterator it = getTermDatabase()->d_func_map_trie.begin(); it != getTermDatabase()->d_func_map_trie.end(); ++it ){
+    if( !getTermDatabase()->d_op_map[it->first].empty() ){
+      Node nn = getTermDatabase()->d_op_map[it->first][0];
+      if( d_cg->isHandledTerm( nn ) && nn.getKind()!=APPLY_SELECTOR_TOTAL && !nn.getType().isBoolean() ){
+        bool do_enum = true;
+        //check if we have enumerated ground terms
+        if( nn.getKind()==APPLY_UF ){
+          if( !d_cg->hasEnumeratedUf( nn ) ){
+            do_enum = false;
+          }
+        }
+        if( do_enum ){
+          d_funcs.push_back( it->first );
+          for( unsigned i=0; i<nn.getNumChildren(); i++ ){
+            d_func_args[it->first].push_back( nn[i].getType() );
+          }
+          d_func_kind[it->first] = nn.getKind();
+          d_typ_tg_funcs[tnull].push_back( it->first );
+          d_typ_tg_funcs[nn.getType()].push_back( it->first );
+          d_tg_func_param[it->first] = ( nn.getMetaKind() == kind::metakind::PARAMETERIZED );
+          Trace("sg-rel-sig") << "Will enumerate function applications of : " << it->first << ", #args = " << d_func_args[it->first].size() << ", kind = " << nn.getKind() << std::endl;
+          getTermDatabase()->computeUfEqcTerms( it->first );
+        }
+      }
+    }
+  }
+  //shuffle functions
+  for( std::map< TypeNode, std::vector< TNode > >::iterator it = d_typ_tg_funcs.begin(); it != d_typ_tg_funcs.end(); ++it ){
+    std::random_shuffle( it->second.begin(), it->second.end() );
+    if( it->first.isNull() ){
+      Trace("sg-gen-tg-debug") << "In this order : ";
+      for( unsigned i=0; i<it->second.size(); i++ ){
+        Trace("sg-gen-tg-debug") << it->second[i] << " ";
+      }
+      Trace("sg-gen-tg-debug") << std::endl;
+    }
+  }
+}
+
+void TermGenEnv::reset( unsigned depth, bool genRelevant, TypeNode tn ) {
+  Assert( d_tg_alloc.empty() );
+  d_tg_alloc.clear();
+
+  if( genRelevant ){
+    for( unsigned i=0; i<2; i++ ){
+      d_ccand_eqc[i].clear();
+      d_ccand_eqc[i].push_back( d_relevant_eqc[i] );
+    }
+  }
+
+  d_tg_id = 0;
+  d_tg_gdepth = 0;
+  d_tg_gdepth_limit = depth;
+  d_gen_relevant_terms = genRelevant;
+  d_tg_alloc[0].reset( this, tn );
+}
+
+bool TermGenEnv::getNextTerm() {
+  if( d_tg_alloc[0].getNextTerm( this, d_tg_gdepth_limit ) ){
+    Assert( (int)d_tg_alloc[0].getGeneralizationDepth( this )<=d_tg_gdepth_limit );
+    if( (int)d_tg_alloc[0].getGeneralizationDepth( this )!=d_tg_gdepth_limit ){
+      return getNextTerm();
+    }else{
+      return true;
+    }
+  }else{
+    return false;
+  }
+}
+
+//reset matching
+void TermGenEnv::resetMatching( TNode eqc, unsigned mode ) {
+  d_tg_alloc[0].resetMatching( this, eqc, mode );
+}
+
+//get next match
+bool TermGenEnv::getNextMatch( TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs ) {
+  return d_tg_alloc[0].getNextMatch( this, eqc, subs, rev_subs );
+}
+
+//get term
+Node TermGenEnv::getTerm() {
+  return d_tg_alloc[0].getTerm( this );
+}
+
+void TermGenEnv::debugPrint( const char * c, const char * cd ) {
+  d_tg_alloc[0].debugPrint( this, c, cd );
+}
+
+unsigned TermGenEnv::getNumTgVars( TypeNode tn ) {
+  return d_var_id[tn];
+}
+
+bool TermGenEnv::allowVar( TypeNode tn ) {
+  std::map< TypeNode, unsigned >::iterator it = d_var_limit.find( tn );
+  if( it==d_var_limit.end() ){
+    return true;
+  }else{
+    return d_var_id[tn]<it->second;
+  }
+}
+
+void TermGenEnv::addVar( TypeNode tn ) {
+  d_var_id[tn]++;
+}
+
+void TermGenEnv::removeVar( TypeNode tn ) {
+  d_var_id[tn]--;
+  //d_var_eq_tg.pop_back();
+  //d_var_tg.pop_back();
+}
+
+unsigned TermGenEnv::getNumTgFuncs( TypeNode tn ) {
+  return d_typ_tg_funcs[tn].size();
+}
+
+TNode TermGenEnv::getTgFunc( TypeNode tn, unsigned i ) {
+  return d_typ_tg_funcs[tn][i];
+}
+
+Node TermGenEnv::getFreeVar( TypeNode tn, unsigned i ) {
+  return d_cg->getFreeVar( tn, i );
+}
+
+bool TermGenEnv::considerCurrentTerm() {
+  Assert( !d_tg_alloc.empty() );
+
+  //if generalization depth is too large, don't consider it
+  unsigned i = d_tg_alloc.size();
+  Trace("sg-gen-tg-debug") << "Consider term ";
+  d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );
+  Trace("sg-gen-tg-debug") << "?  curr term size = " << d_tg_alloc.size() << ", last status = " << d_tg_alloc[i-1].d_status;
+  Trace("sg-gen-tg-debug") << std::endl;
+
+  if( d_tg_gdepth_limit>=0 && d_tg_alloc[0].getGeneralizationDepth( this )>(unsigned)d_tg_gdepth_limit ){
+    Trace("sg-gen-consider-term") << "-> generalization depth of ";
+    d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-tg-debug" );
+    Trace("sg-gen-consider-term") << " is too high " << d_tg_gdepth << " " << d_tg_alloc[0].getGeneralizationDepth( this ) << ", do not consider." << std::endl;
+    return false;
+  }
+
+  //----optimizations
+  /*
+  if( d_tg_alloc[i-1].d_status==1 ){
+  }else if( d_tg_alloc[i-1].d_status==2 ){
+  }else if( d_tg_alloc[i-1].d_status==5 ){
+  }else{
+    Trace("sg-gen-tg-debug") << "Bad tg: " << &d_tg_alloc[i-1] << std::endl;
+    Assert( false );
+  }
+  */
+  //if equated two variables, first check if context-independent TODO
+  //----end optimizations
+
+
+  //check based on which candidate equivalence classes match
+  if( d_gen_relevant_terms ){
+    Trace("sg-gen-tg-debug") << "Filter based on relevant ground EQC";
+    Trace("sg-gen-tg-debug") << ", #eqc to try = " << d_ccand_eqc[0][i-1].size() << "/" << d_ccand_eqc[1][i-1].size() << std::endl;
+
+    Assert( d_ccand_eqc[0].size()>=2 );
+    Assert( d_ccand_eqc[0].size()==d_ccand_eqc[1].size() );
+    Assert( d_ccand_eqc[0].size()==d_tg_id+1 );
+    Assert( d_tg_id==d_tg_alloc.size() );
+    for( unsigned r=0; r<2; r++ ){
+      d_ccand_eqc[r][i].clear();
+    }
+
+    //re-check feasibility of EQC
+    for( unsigned r=0; r<2; r++ ){
+      for( unsigned j=0; j<d_ccand_eqc[r][i-1].size(); j++ ){
+        std::map< TypeNode, std::map< unsigned, TNode > > subs;
+        std::map< TNode, bool > rev_subs;
+        unsigned mode;
+        if( r==0 ){
+          mode = d_cg->optReqDistinctVarPatterns() ? ( 1 << 0 ) : 0;
+          mode = mode | (1 << 2 );
+        }else{
+          mode =  1 << 1;
+        }
+        d_tg_alloc[0].resetMatching( this, d_ccand_eqc[r][i-1][j], mode );
+        if( d_tg_alloc[0].getNextMatch( this, d_ccand_eqc[r][i-1][j], subs, rev_subs ) ){
+          d_ccand_eqc[r][i].push_back( d_ccand_eqc[r][i-1][j] );
+        }
+      }
+    }
+    for( unsigned r=0; r<2; r++ ){
+      Trace("sg-gen-tg-debug") << "Current eqc of type " << r << " : ";
+      for( unsigned j=0; j<d_ccand_eqc[r][i].size(); j++ ){
+        Trace("sg-gen-tg-debug") << "e" << d_cg->d_em[d_ccand_eqc[r][i][j]] << " ";
+      }
+      Trace("sg-gen-tg-debug") << std::endl;
+    }
+    if( options::conjectureFilterActiveTerms() && d_ccand_eqc[0][i].empty() ){
+      Trace("sg-gen-consider-term") << "Do not consider term of form ";
+      d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-consider-term-debug" );
+      Trace("sg-gen-consider-term") << " since no relevant EQC matches it." << std::endl;
+      return false;
+    }
+    if( options::conjectureFilterModel() && d_ccand_eqc[1][i].empty() ){
+      Trace("sg-gen-consider-term") << "Do not consider term of form ";
+      d_tg_alloc[0].debugPrint( this, "sg-gen-consider-term", "sg-gen-consider-term-debug" );
+      Trace("sg-gen-consider-term") << " since no ground EQC matches it." << std::endl;
+      return false;
+    }
+  }
+  Trace("sg-gen-tg-debug") << "Will consider term ";
+  d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );
+  Trace("sg-gen-tg-debug") << std::endl;
+  Trace("sg-gen-consider-term-debug") << std::endl;
+  return true;
+}
+
+void TermGenEnv::changeContext( bool add ) {
+  if( add ){
+    for( unsigned r=0; r<2; r++ ){
+      d_ccand_eqc[r].push_back( std::vector< TNode >() );
+    }
+    d_tg_id++;
+  }else{
+    for( unsigned r=0; r<2; r++ ){
+      d_ccand_eqc[r].pop_back();
+    }
+    d_tg_id--;
+    Assert( d_tg_alloc.find( d_tg_id )!=d_tg_alloc.end() );
+    d_tg_alloc.erase( d_tg_id );
+  }
+}
+
+bool TermGenEnv::considerCurrentTermCanon( unsigned tg_id ){
+  Assert( tg_id<d_tg_alloc.size() );
+  if( options::conjectureFilterCanonical() ){
+    //check based on a canonicity of the term (if there is one)
+    Trace("sg-gen-tg-debug") << "Consider term canon ";
+    d_tg_alloc[0].debugPrint( this, "sg-gen-tg-debug", "sg-gen-tg-debug" );
+    Trace("sg-gen-tg-debug") << ", tg is [" << tg_id << "]..." << std::endl;
+
+    Node ln = d_tg_alloc[tg_id].getTerm( this );
+    Trace("sg-gen-tg-debug") << "Term is " << ln << std::endl;
+    return d_cg->considerTermCanon( ln, d_gen_relevant_terms );
+  }
+  return true;
+}
+
+bool TermGenEnv::isRelevantFunc( Node f ) {
+  return std::find( d_funcs.begin(), d_funcs.end(), f )!=d_funcs.end();
+}
+TermDb * TermGenEnv::getTermDatabase() {
+  return d_cg->getTermDatabase();
+}
+Node TermGenEnv::getGroundEqc( TNode r ) {
+  return d_cg->getGroundEqc( r );
+}
+bool TermGenEnv::isGroundEqc( TNode r ){
+  return d_cg->isGroundEqc( r );
+}
+bool TermGenEnv::isGroundTerm( TNode n ){
+  return d_cg->isGroundTerm( n );
+}
+
+
+void SubstitutionIndex::addSubstitution( TNode eqc, std::vector< TNode >& vars, std::vector< TNode >& terms, unsigned i ) {
+  if( i==vars.size() ){
+    d_var = eqc;
+  }else{
+    Assert( d_var.isNull() || d_var==vars[i] );
+    d_var = vars[i];
+    d_children[terms[i]].addSubstitution( eqc, vars, terms, i+1 );
+  }
+}
+
+bool SubstitutionIndex::notifySubstitutions( ConjectureGenerator * s, std::map< TNode, TNode >& subs, TNode rhs, unsigned numVars, unsigned i ) {
+  if( i==numVars ){
+    Assert( d_children.empty() );
+    return s->notifySubstitution( d_var, subs, rhs );
+  }else{
+    Assert( i==0 || !d_children.empty() );
+    for( std::map< TNode, SubstitutionIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){
+      Trace("sg-cconj-debug2") << "Try " << d_var << " -> " << it->first << " (" << i << "/" << numVars << ")" << std::endl;
+      subs[d_var] = it->first;
+      if( !it->second.notifySubstitutions( s, subs, rhs, numVars, i+1 ) ){
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+
+void TheoremIndex::addTheorem( std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs ){
+  if( lhs_v.empty() ){
+    if( std::find( d_terms.begin(), d_terms.end(), rhs )==d_terms.end() ){
+      d_terms.push_back( rhs );
+    }
+  }else{
+    unsigned index = lhs_v.size()-1;
+    if( lhs_arg[index]==lhs_v[index].getNumChildren() ){
+      lhs_v.pop_back();
+      lhs_arg.pop_back();
+      addTheorem( lhs_v, lhs_arg, rhs );
+    }else{
+      lhs_arg[index]++;
+      addTheoremNode( lhs_v[index][lhs_arg[index]-1], lhs_v, lhs_arg, rhs );
+    }
+  }
+}
+
+void TheoremIndex::addTheoremNode( TNode curr, std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs ){
+  Trace("thm-db-debug") << "Adding conjecture for subterm " << curr << "..." << std::endl;
+  if( curr.hasOperator() ){
+    lhs_v.push_back( curr );
+    lhs_arg.push_back( 0 );
+    d_children[curr.getOperator()].addTheorem( lhs_v, lhs_arg, rhs );
+  }else{
+    Assert( curr.getKind()==kind::BOUND_VARIABLE );
+    TypeNode tn = curr.getType();
+    Assert( d_var[tn].isNull() || d_var[tn]==curr );
+    d_var[tn] = curr;
+    d_children[curr].addTheorem( lhs_v, lhs_arg, rhs );
+  }
+}
+
+void TheoremIndex::getEquivalentTerms( std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,
+                                       std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,
+                                       std::vector< Node >& terms ) {
+  Trace("thm-db-debug") << "Get equivalent terms " << n_v.size() << " " << n_arg.size() << std::endl;
+  if( n_v.empty() ){
+    Trace("thm-db-debug") << "Number of terms : " << d_terms.size() << std::endl;
+    //apply substutitions to RHS's
+    for( unsigned i=0; i<d_terms.size(); i++ ){
+      Node n = d_terms[i].substitute( vars.begin(), vars.end(), subs.begin(), subs.end() );
+      terms.push_back( n );
+    }
+  }else{
+    unsigned index = n_v.size()-1;
+    if( n_arg[index]==n_v[index].getNumChildren() ){
+      n_v.pop_back();
+      n_arg.pop_back();
+      getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );
+    }else{
+      n_arg[index]++;
+      getEquivalentTermsNode( n_v[index][n_arg[index]-1], n_v, n_arg, smap, vars, subs, terms );
+    }
+  }
+}
+
+void TheoremIndex::getEquivalentTermsNode( Node curr, std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,
+                                           std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,
+                                           std::vector< Node >& terms ) {
+  Trace("thm-db-debug") << "Get equivalent based on subterm " << curr << "..." << std::endl;
+  if( curr.hasOperator() ){
+    Trace("thm-db-debug") << "Check based on operator..." << std::endl;
+    std::map< TNode, TheoremIndex >::iterator it = d_children.find( curr.getOperator() );
+    if( it!=d_children.end() ){
+      n_v.push_back( curr );
+      n_arg.push_back( 0 );
+      it->second.getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );
+    }
+    Trace("thm-db-debug") << "...done check based on operator" << std::endl;
+  }
+  TypeNode tn = curr.getType();
+  std::map< TypeNode, TNode >::iterator itt = d_var.find( tn );
+  if( itt!=d_var.end() ){
+    Trace("thm-db-debug") << "Check for substitution with " << itt->second << "..." << std::endl;
+    Assert( curr.getType()==itt->second.getType() );
+    //add to substitution if possible
+    bool success = false;
+    std::map< TNode, TNode >::iterator it = smap.find( itt->second );
+    if( it==smap.end() ){
+      smap[itt->second] = curr;
+      vars.push_back( itt->second );
+      subs.push_back( curr );
+      success = true;
+    }else if( it->second==curr ){
+      success = true;
+    }else{
+      //also check modulo equality (in universal equality engine)
+    }
+    Trace("thm-db-debug") << "...check for substitution with " << itt->second << ", success = " << success << "." << std::endl;
+    if( success ){
+      d_children[itt->second].getEquivalentTerms( n_v, n_arg, smap, vars, subs, terms );
+    }
+  }
+}
+
+void TheoremIndex::debugPrint( const char * c, unsigned ind ) {
+  for( std::map< TNode, TheoremIndex >::iterator it = d_children.begin(); it != d_children.end(); ++it ){
+    for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }
+    Trace(c) << it->first << std::endl;
+    it->second.debugPrint( c, ind+1 );
+  }
+  if( !d_terms.empty() ){
+    for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }
+    Trace(c) << "{";
+    for( unsigned i=0; i<d_terms.size(); i++ ){
+      Trace(c) << " " << d_terms[i];
+    }
+    Trace(c) << " }" << std::endl;
+  }
+  //if( !d_var.isNull() ){
+  //  for( unsigned i=0; i<ind; i++ ){ Trace(c) << "  "; }
+  //  Trace(c) << "var:" << d_var << std::endl;
+  //}
+}
+
+bool ConjectureGenerator::optReqDistinctVarPatterns() { return false; }
+bool ConjectureGenerator::optFilterUnknown() { return true; }  //may change
+int ConjectureGenerator::optFilterScoreThreshold() { return 1; }
+unsigned ConjectureGenerator::optFullCheckFrequency() { return 1; }
+
+bool ConjectureGenerator::optStatsOnly() { return false; }
+
+}
index 48694c99a69c991b4680ead4428a843b1c4455ee..6f99777f4384552410274002872ca6d33739372c 100644 (file)
-/*********************                                                        */\r
-/*! \file conjecture_generator.h\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief conjecture generator class\r
- **/\r
-\r
-#include "cvc4_private.h"\r
-\r
-#ifndef CONJECTURE_GENERATOR_H\r
-#define CONJECTURE_GENERATOR_H\r
-\r
-#include "context/cdhashmap.h"\r
-#include "context/cdchunk_list.h"\r
-#include "theory/quantifiers_engine.h"\r
-#include "theory/type_enumerator.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace quantifiers {\r
-\r
-class TermArgTrie;\r
-\r
-//algorithm for computing candidate subgoals\r
-\r
-class ConjectureGenerator;\r
-\r
-// operator independent index of arguments for an EQC\r
-class OpArgIndex\r
-{\r
-public:\r
-  std::map< TNode, OpArgIndex > d_child;\r
-  std::vector< TNode > d_ops;\r
-  std::vector< TNode > d_op_terms;\r
-  void addTerm( ConjectureGenerator * s, TNode n, unsigned index = 0 );\r
-  Node getGroundTerm( ConjectureGenerator * s, std::vector< TNode >& args );\r
-  void getGroundTerms( ConjectureGenerator * s, std::vector< TNode >& terms );\r
-};\r
-\r
-class PatternTypIndex\r
-{\r
-public:\r
-  std::vector< TNode > d_terms;\r
-  std::map< TypeNode, std::map< unsigned, PatternTypIndex > > d_children;\r
-  void clear() {\r
-    d_terms.clear();\r
-    d_children.clear();\r
-  }\r
-};\r
-\r
-class SubstitutionIndex\r
-{\r
-public:\r
-  //current variable, or ground EQC if d_children.empty()\r
-  TNode d_var;\r
-  std::map< TNode, SubstitutionIndex > d_children;\r
-  //add substitution\r
-  void addSubstitution( TNode eqc, std::vector< TNode >& vars, std::vector< TNode >& terms, unsigned i = 0 );\r
-  //notify substitutions\r
-  bool notifySubstitutions( ConjectureGenerator * s, std::map< TNode, TNode >& subs, TNode rhs, unsigned numVars, unsigned i = 0 );\r
-};\r
-\r
-class TermGenEnv;\r
-\r
-class TermGenerator\r
-{\r
-private:\r
-  unsigned calculateGeneralizationDepth( TermGenEnv * s, std::map< TypeNode, std::vector< int > >& fvs );\r
-public:\r
-  TermGenerator(){}\r
-  TypeNode d_typ;\r
-  unsigned d_id;\r
-  //1 : consider as unique variable\r
-  //2 : consider equal to another variable\r
-  //5 : consider a function application\r
-  unsigned d_status;\r
-  int d_status_num;\r
-  //for function applications: the number of children you have built\r
-  int d_status_child_num;\r
-  //children (pointers to TermGenerators)\r
-  std::vector< unsigned > d_children;\r
-\r
-  //match status\r
-  int d_match_status;\r
-  int d_match_status_child_num;\r
-  //match mode bits\r
-  //0 : different variables must have different matches\r
-  //1 : variables must map to ground terms\r
-  //2 : variables must map to non-ground terms\r
-  unsigned d_match_mode;\r
-  //children\r
-  std::vector< std::map< TNode, TermArgTrie >::iterator > d_match_children;\r
-  std::vector< std::map< TNode, TermArgTrie >::iterator > d_match_children_end;\r
-\r
-  void reset( TermGenEnv * s, TypeNode tn );\r
-  bool getNextTerm( TermGenEnv * s, unsigned depth );\r
-  void resetMatching( TermGenEnv * s, TNode eqc, unsigned mode );\r
-  bool getNextMatch( TermGenEnv * s, TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs );\r
-\r
-  unsigned getDepth( TermGenEnv * s );\r
-  unsigned getGeneralizationDepth( TermGenEnv * s );\r
-  Node getTerm( TermGenEnv * s );\r
-\r
-  void debugPrint( TermGenEnv * s, const char * c, const char * cd );\r
-};\r
-\r
-\r
-class TermGenEnv\r
-{\r
-public:\r
-  //collect signature information\r
-  void collectSignatureInformation();\r
-  //reset function\r
-  void reset( unsigned gdepth, bool genRelevant, TypeNode tgen );\r
-  //get next term\r
-  bool getNextTerm();\r
-  //reset matching\r
-  void resetMatching( TNode eqc, unsigned mode );\r
-  //get next match\r
-  bool getNextMatch( TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs );\r
-  //get term\r
-  Node getTerm();\r
-  //debug print\r
-  void debugPrint( const char * c, const char * cd );\r
-\r
-  //conjecture generation\r
-  ConjectureGenerator * d_cg;\r
-  //the current number of enumerated variables per type\r
-  std::map< TypeNode, unsigned > d_var_id;\r
-  //the limit of number of variables per type to enumerate\r
-  std::map< TypeNode, unsigned > d_var_limit;\r
-  //the functions we can currently generate\r
-  std::map< TypeNode, std::vector< TNode > > d_typ_tg_funcs;\r
-  // whether functions must add operators\r
-  std::map< TNode, bool > d_tg_func_param;\r
-  //the equivalence classes (if applicable) that match the currently generated term\r
-  bool d_gen_relevant_terms;\r
-  //relevant equivalence classes\r
-  std::vector< TNode > d_relevant_eqc[2];\r
-  //candidate equivalence classes\r
-  std::vector< std::vector< TNode > > d_ccand_eqc[2];\r
-  //the term generation objects\r
-  unsigned d_tg_id;\r
-  std::map< unsigned, TermGenerator > d_tg_alloc;\r
-  unsigned d_tg_gdepth;\r
-  int d_tg_gdepth_limit;\r
-\r
-  //all functions\r
-  std::vector< TNode > d_funcs;\r
-  //function to kind map\r
-  std::map< TNode, Kind > d_func_kind;\r
-  //type of each argument of the function\r
-  std::map< TNode, std::vector< TypeNode > > d_func_args;\r
-\r
-  //access functions\r
-  unsigned getNumTgVars( TypeNode tn );\r
-  bool allowVar( TypeNode tn );\r
-  void addVar( TypeNode tn );\r
-  void removeVar( TypeNode tn );\r
-  unsigned getNumTgFuncs( TypeNode tn );\r
-  TNode getTgFunc( TypeNode tn, unsigned i );\r
-  Node getFreeVar( TypeNode tn, unsigned i );\r
-  bool considerCurrentTerm();\r
-  bool considerCurrentTermCanon( unsigned tg_id );\r
-  void changeContext( bool add );\r
-  bool isRelevantFunc( Node f );\r
-  //carry\r
-  TermDb * getTermDatabase();\r
-  Node getGroundEqc( TNode r );\r
-  bool isGroundEqc( TNode r );\r
-  bool isGroundTerm( TNode n );\r
-};\r
-\r
-\r
-\r
-class TheoremIndex\r
-{\r
-private:\r
-  void addTheorem( std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs );\r
-  void addTheoremNode( TNode curr, std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs );\r
-  void getEquivalentTerms( std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,\r
-                           std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,\r
-                           std::vector< Node >& terms );\r
-  void getEquivalentTermsNode( Node curr, std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,\r
-                               std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,\r
-                               std::vector< Node >& terms );\r
-public:\r
-  std::map< TypeNode, TNode > d_var;\r
-  std::map< TNode, TheoremIndex > d_children;\r
-  std::vector< Node > d_terms;\r
-\r
-  void addTheorem( TNode lhs, TNode rhs ) {\r
-    std::vector< TNode > v;\r
-    std::vector< unsigned > a;\r
-    addTheoremNode( lhs, v, a, rhs );\r
-  }\r
-  void getEquivalentTerms( TNode n, std::vector< Node >& terms ) {\r
-    std::vector< TNode > nv;\r
-    std::vector< unsigned > na;\r
-    std::map< TNode, TNode > smap;\r
-    std::vector< TNode > vars;\r
-    std::vector< TNode > subs;\r
-    getEquivalentTermsNode( n, nv, na, smap, vars, subs, terms );\r
-  }\r
-  void clear(){\r
-    d_var.clear();\r
-    d_children.clear();\r
-    d_terms.clear();\r
-  }\r
-  void debugPrint( const char * c, unsigned ind = 0 );\r
-};\r
-\r
-\r
-\r
-class ConjectureGenerator : public QuantifiersModule\r
-{\r
-  friend class OpArgIndex;\r
-  friend class PatGen;\r
-  friend class PatternGenEqc;\r
-  friend class PatternGen;\r
-  friend class SubsEqcIndex;\r
-  friend class TermGenerator;\r
-  friend class TermGenEnv;\r
-  typedef context::CDChunkList<Node> NodeList;\r
-  typedef context::CDHashMap< Node, Node, NodeHashFunction > NodeMap;\r
-  typedef context::CDHashMap< Node, bool, NodeHashFunction > BoolMap;\r
-//this class maintains a congruence closure for *universal* facts\r
-private:\r
-  //notification class for equality engine\r
-  class NotifyClass : public eq::EqualityEngineNotify {\r
-    ConjectureGenerator& d_sg;\r
-  public:\r
-    NotifyClass(ConjectureGenerator& sg): d_sg(sg) {}\r
-    bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; }\r
-    bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; }\r
-    bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { return true; }\r
-    void eqNotifyConstantTermMerge(TNode t1, TNode t2) { }\r
-    void eqNotifyNewClass(TNode t) { d_sg.eqNotifyNewClass(t); }\r
-    void eqNotifyPreMerge(TNode t1, TNode t2) { d_sg.eqNotifyPreMerge(t1, t2); }\r
-    void eqNotifyPostMerge(TNode t1, TNode t2) { d_sg.eqNotifyPostMerge(t1, t2); }\r
-    void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {d_sg.eqNotifyDisequal(t1, t2, reason); }\r
-  };/* class ConjectureGenerator::NotifyClass */\r
-  /** The notify class */\r
-  NotifyClass d_notify;\r
-  class EqcInfo{\r
-  public:\r
-    EqcInfo( context::Context* c );\r
-    //representative\r
-    context::CDO< Node > d_rep;\r
-  };\r
-  /** get or make eqc info */\r
-  EqcInfo* getOrMakeEqcInfo( TNode n, bool doMake = false );\r
-  /** (universal) equaltity engine */\r
-  eq::EqualityEngine d_uequalityEngine;\r
-  /** pending adds */\r
-  std::vector< Node > d_upendingAdds;\r
-  /** relevant terms */\r
-  std::map< Node, bool > d_urelevant_terms;\r
-  /** information necessary for equivalence classes */\r
-  std::map< Node, EqcInfo* > d_eqc_info;\r
-  /** called when a new equivalance class is created */\r
-  void eqNotifyNewClass(TNode t);\r
-  /** called when two equivalance classes will merge */\r
-  void eqNotifyPreMerge(TNode t1, TNode t2);\r
-  /** called when two equivalance classes have merged */\r
-  void eqNotifyPostMerge(TNode t1, TNode t2);\r
-  /** called when two equivalence classes are made disequal */\r
-  void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);\r
-  /** are universal equal */\r
-  bool areUniversalEqual( TNode n1, TNode n2 );\r
-  /** are universal disequal */\r
-  bool areUniversalDisequal( TNode n1, TNode n2 );\r
-  /** get universal representative */\r
-  TNode getUniversalRepresentative( TNode n, bool add = false );\r
-  /** set relevant */\r
-  void setUniversalRelevant( TNode n );\r
-  /** ordering for universal terms */\r
-  bool isUniversalLessThan( TNode rt1, TNode rt2 );\r
-\r
-  /** the nodes we have reported as canonical representative */\r
-  std::vector< TNode > d_ue_canon;\r
-  /** is reported canon */\r
-  bool isReportedCanon( TNode n );\r
-  /** mark that term has been reported as canonical rep */\r
-  void markReportedCanon( TNode n );\r
-\r
-private:  //information regarding the conjectures\r
-  /** list of all conjectures */\r
-  std::vector< Node > d_conjectures;\r
-  /** list of all waiting conjectures */\r
-  std::vector< Node > d_waiting_conjectures_lhs;\r
-  std::vector< Node > d_waiting_conjectures_rhs;\r
-  std::vector< int > d_waiting_conjectures_score;\r
-  /** map of currently considered equality conjectures */\r
-  std::map< Node, std::vector< Node > > d_waiting_conjectures;\r
-  /** map of equality conjectures */\r
-  std::map< Node, std::vector< Node > > d_eq_conjectures;\r
-  /** currently existing conjectures in equality engine */\r
-  BoolMap d_ee_conjectures;\r
-  /** conjecture index */\r
-  TheoremIndex d_thm_index;\r
-private:  //free variable list\r
-  //free variables\r
-  std::map< TypeNode, std::vector< Node > > d_free_var;\r
-  //map from free variable to FV#\r
-  std::map< TNode, unsigned > d_free_var_num;\r
-  // get canonical free variable #i of type tn\r
-  Node getFreeVar( TypeNode tn, unsigned i );\r
-  // get canonical term, return null if it contains a term apart from handled signature\r
-  Node getCanonicalTerm( TNode n, std::map< TypeNode, unsigned >& var_count, std::map< TNode, TNode >& subs );\r
-private:  //information regarding the terms\r
-  //relevant patterns (the LHS's)\r
-  std::map< TypeNode, std::vector< Node > > d_rel_patterns;\r
-  //total number of unique variables\r
-  std::map< TNode, unsigned > d_rel_pattern_var_sum;\r
-  //by types\r
-  PatternTypIndex d_rel_pattern_typ_index;\r
-  // substitution to ground EQC index\r
-  std::map< TNode, SubstitutionIndex > d_rel_pattern_subs_index;\r
-  //patterns (the RHS's)\r
-  std::map< TypeNode, std::vector< Node > > d_patterns;\r
-  //patterns to # variables per type\r
-  std::map< TNode, std::map< TypeNode, unsigned > > d_pattern_var_id;\r
-  // # duplicated variables\r
-  std::map< TNode, unsigned > d_pattern_var_duplicate;\r
-  // is normal pattern?  (variables allocated in canonical way left to right)\r
-  std::map< TNode, int > d_pattern_is_normal;\r
-  std::map< TNode, int > d_pattern_is_relevant;\r
-  // patterns to a count of # operators (variables and functions)\r
-  std::map< TNode, std::map< TNode, unsigned > > d_pattern_fun_id;\r
-  // term size\r
-  std::map< TNode, unsigned > d_pattern_fun_sum;\r
-  // collect functions\r
-  unsigned collectFunctions( TNode opat, TNode pat, std::map< TNode, unsigned >& funcs,\r
-                             std::map< TypeNode, unsigned >& mnvn, std::map< TypeNode, unsigned >& mxvn );\r
-  // add pattern\r
-  void registerPattern( Node pat, TypeNode tpat );\r
-private: //for debugging\r
-  std::map< TNode, unsigned > d_em;\r
-  unsigned d_conj_count;\r
-public:\r
-  //term generation environment\r
-  TermGenEnv d_tge;\r
-  //consider term canon\r
-  bool considerTermCanon( Node ln, bool genRelevant );\r
-public:  //for generalization\r
-  //generalizations\r
-  bool isGeneralization( TNode patg, TNode pat ) {\r
-    std::map< TNode, TNode > subs;\r
-    return isGeneralization( patg, pat, subs );\r
-  }\r
-  bool isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs );\r
-  // get generalization depth\r
-  int calculateGeneralizationDepth( TNode n, std::vector< TNode >& fv );\r
-private:\r
-  //predicate for type\r
-  std::map< TypeNode, Node > d_typ_pred;\r
-  //get predicate for type\r
-  Node getPredicateForType( TypeNode tn );\r
-  //\r
-  void getEnumerateUfTerm( Node n, unsigned num, std::vector< Node >& terms );\r
-  //\r
-  void getEnumeratePredUfTerm( Node n, unsigned num, std::vector< Node >& terms );\r
-  // uf operators enumerated\r
-  std::map< Node, bool > d_uf_enum;\r
-public:  //for property enumeration\r
-  //process this candidate conjecture\r
-  void processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth );\r
-  //whether it should be considered, negative : no, positive returns score\r
-  int considerCandidateConjecture( TNode lhs, TNode rhs );\r
-  //notified of a substitution\r
-  bool notifySubstitution( TNode glhs, std::map< TNode, TNode >& subs, TNode rhs );\r
-  //confirmation count\r
-  unsigned d_subs_confirmCount;\r
-  //individual witnesses (for range)\r
-  std::vector< TNode > d_subs_confirmWitnessRange;\r
-  //individual witnesses (for domain)\r
-  std::map< TNode, std::vector< TNode > > d_subs_confirmWitnessDomain;\r
-  //number of ground substitutions whose equality is unknown\r
-  unsigned d_subs_unkCount;\r
-private:  //information about ground equivalence classes\r
-  TNode d_bool_eqc[2];\r
-  std::map< TNode, Node > d_ground_eqc_map;\r
-  std::vector< TNode > d_ground_terms;\r
-  //operator independent term index\r
-  std::map< TNode, OpArgIndex > d_op_arg_index;\r
-  //is handled term\r
-  bool isHandledTerm( TNode n );\r
-  Node getGroundEqc( TNode r );\r
-  bool isGroundEqc( TNode r );\r
-  bool isGroundTerm( TNode n );\r
-  //has enumerated UF\r
-  bool hasEnumeratedUf( Node n );\r
-  // count of full effort checks\r
-  unsigned d_fullEffortCount;\r
-  // has added lemma\r
-  bool d_hasAddedLemma;\r
-  //flush the waiting conjectures\r
-  unsigned flushWaitingConjectures( unsigned& addedLemmas, int ldepth, int rdepth );\r
-public:\r
-  ConjectureGenerator( QuantifiersEngine * qe, context::Context* c );\r
-  ~ConjectureGenerator() throw() {}\r
-  /* needs check */\r
-  bool needsCheck( Theory::Effort e );\r
-  /* reset at a round */\r
-  void reset_round( Theory::Effort e );\r
-  /* Call during quantifier engine's check */\r
-  void check( Theory::Effort e, unsigned quant_e );\r
-  /* Called for new quantifiers */\r
-  void registerQuantifier( Node q );\r
-  void assertNode( Node n );\r
-  /** Identify this module (for debugging, dynamic configuration, etc..) */\r
-  std::string identify() const { return "ConjectureGenerator"; }\r
-//options\r
-private:\r
-  bool optReqDistinctVarPatterns();\r
-  bool optFilterUnknown();\r
-  int optFilterScoreThreshold();\r
-  unsigned optFullCheckFrequency();\r
-  unsigned optFullCheckConjectures();\r
-\r
-  bool optStatsOnly();\r
-};\r
-\r
-\r
-}\r
-}\r
-}\r
-\r
-#endif\r
+/*********************                                                        */
+/*! \file conjecture_generator.h
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief conjecture generator class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef CONJECTURE_GENERATOR_H
+#define CONJECTURE_GENERATOR_H
+
+#include "context/cdhashmap.h"
+#include "context/cdchunk_list.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/type_enumerator.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class TermArgTrie;
+
+//algorithm for computing candidate subgoals
+
+class ConjectureGenerator;
+
+// operator independent index of arguments for an EQC
+class OpArgIndex
+{
+public:
+  std::map< TNode, OpArgIndex > d_child;
+  std::vector< TNode > d_ops;
+  std::vector< TNode > d_op_terms;
+  void addTerm( ConjectureGenerator * s, TNode n, unsigned index = 0 );
+  Node getGroundTerm( ConjectureGenerator * s, std::vector< TNode >& args );
+  void getGroundTerms( ConjectureGenerator * s, std::vector< TNode >& terms );
+};
+
+class PatternTypIndex
+{
+public:
+  std::vector< TNode > d_terms;
+  std::map< TypeNode, std::map< unsigned, PatternTypIndex > > d_children;
+  void clear() {
+    d_terms.clear();
+    d_children.clear();
+  }
+};
+
+class SubstitutionIndex
+{
+public:
+  //current variable, or ground EQC if d_children.empty()
+  TNode d_var;
+  std::map< TNode, SubstitutionIndex > d_children;
+  //add substitution
+  void addSubstitution( TNode eqc, std::vector< TNode >& vars, std::vector< TNode >& terms, unsigned i = 0 );
+  //notify substitutions
+  bool notifySubstitutions( ConjectureGenerator * s, std::map< TNode, TNode >& subs, TNode rhs, unsigned numVars, unsigned i = 0 );
+};
+
+class TermGenEnv;
+
+class TermGenerator
+{
+private:
+  unsigned calculateGeneralizationDepth( TermGenEnv * s, std::map< TypeNode, std::vector< int > >& fvs );
+public:
+  TermGenerator(){}
+  TypeNode d_typ;
+  unsigned d_id;
+  //1 : consider as unique variable
+  //2 : consider equal to another variable
+  //5 : consider a function application
+  unsigned d_status;
+  int d_status_num;
+  //for function applications: the number of children you have built
+  int d_status_child_num;
+  //children (pointers to TermGenerators)
+  std::vector< unsigned > d_children;
+
+  //match status
+  int d_match_status;
+  int d_match_status_child_num;
+  //match mode bits
+  //0 : different variables must have different matches
+  //1 : variables must map to ground terms
+  //2 : variables must map to non-ground terms
+  unsigned d_match_mode;
+  //children
+  std::vector< std::map< TNode, TermArgTrie >::iterator > d_match_children;
+  std::vector< std::map< TNode, TermArgTrie >::iterator > d_match_children_end;
+
+  void reset( TermGenEnv * s, TypeNode tn );
+  bool getNextTerm( TermGenEnv * s, unsigned depth );
+  void resetMatching( TermGenEnv * s, TNode eqc, unsigned mode );
+  bool getNextMatch( TermGenEnv * s, TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs );
+
+  unsigned getDepth( TermGenEnv * s );
+  unsigned getGeneralizationDepth( TermGenEnv * s );
+  Node getTerm( TermGenEnv * s );
+
+  void debugPrint( TermGenEnv * s, const char * c, const char * cd );
+};
+
+
+class TermGenEnv
+{
+public:
+  //collect signature information
+  void collectSignatureInformation();
+  //reset function
+  void reset( unsigned gdepth, bool genRelevant, TypeNode tgen );
+  //get next term
+  bool getNextTerm();
+  //reset matching
+  void resetMatching( TNode eqc, unsigned mode );
+  //get next match
+  bool getNextMatch( TNode eqc, std::map< TypeNode, std::map< unsigned, TNode > >& subs, std::map< TNode, bool >& rev_subs );
+  //get term
+  Node getTerm();
+  //debug print
+  void debugPrint( const char * c, const char * cd );
+
+  //conjecture generation
+  ConjectureGenerator * d_cg;
+  //the current number of enumerated variables per type
+  std::map< TypeNode, unsigned > d_var_id;
+  //the limit of number of variables per type to enumerate
+  std::map< TypeNode, unsigned > d_var_limit;
+  //the functions we can currently generate
+  std::map< TypeNode, std::vector< TNode > > d_typ_tg_funcs;
+  // whether functions must add operators
+  std::map< TNode, bool > d_tg_func_param;
+  //the equivalence classes (if applicable) that match the currently generated term
+  bool d_gen_relevant_terms;
+  //relevant equivalence classes
+  std::vector< TNode > d_relevant_eqc[2];
+  //candidate equivalence classes
+  std::vector< std::vector< TNode > > d_ccand_eqc[2];
+  //the term generation objects
+  unsigned d_tg_id;
+  std::map< unsigned, TermGenerator > d_tg_alloc;
+  unsigned d_tg_gdepth;
+  int d_tg_gdepth_limit;
+
+  //all functions
+  std::vector< TNode > d_funcs;
+  //function to kind map
+  std::map< TNode, Kind > d_func_kind;
+  //type of each argument of the function
+  std::map< TNode, std::vector< TypeNode > > d_func_args;
+
+  //access functions
+  unsigned getNumTgVars( TypeNode tn );
+  bool allowVar( TypeNode tn );
+  void addVar( TypeNode tn );
+  void removeVar( TypeNode tn );
+  unsigned getNumTgFuncs( TypeNode tn );
+  TNode getTgFunc( TypeNode tn, unsigned i );
+  Node getFreeVar( TypeNode tn, unsigned i );
+  bool considerCurrentTerm();
+  bool considerCurrentTermCanon( unsigned tg_id );
+  void changeContext( bool add );
+  bool isRelevantFunc( Node f );
+  //carry
+  TermDb * getTermDatabase();
+  Node getGroundEqc( TNode r );
+  bool isGroundEqc( TNode r );
+  bool isGroundTerm( TNode n );
+};
+
+
+
+class TheoremIndex
+{
+private:
+  void addTheorem( std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs );
+  void addTheoremNode( TNode curr, std::vector< TNode >& lhs_v, std::vector< unsigned >& lhs_arg, TNode rhs );
+  void getEquivalentTerms( std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,
+                           std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,
+                           std::vector< Node >& terms );
+  void getEquivalentTermsNode( Node curr, std::vector< TNode >& n_v, std::vector< unsigned >& n_arg,
+                               std::map< TNode, TNode >& smap, std::vector< TNode >& vars, std::vector< TNode >& subs,
+                               std::vector< Node >& terms );
+public:
+  std::map< TypeNode, TNode > d_var;
+  std::map< TNode, TheoremIndex > d_children;
+  std::vector< Node > d_terms;
+
+  void addTheorem( TNode lhs, TNode rhs ) {
+    std::vector< TNode > v;
+    std::vector< unsigned > a;
+    addTheoremNode( lhs, v, a, rhs );
+  }
+  void getEquivalentTerms( TNode n, std::vector< Node >& terms ) {
+    std::vector< TNode > nv;
+    std::vector< unsigned > na;
+    std::map< TNode, TNode > smap;
+    std::vector< TNode > vars;
+    std::vector< TNode > subs;
+    getEquivalentTermsNode( n, nv, na, smap, vars, subs, terms );
+  }
+  void clear(){
+    d_var.clear();
+    d_children.clear();
+    d_terms.clear();
+  }
+  void debugPrint( const char * c, unsigned ind = 0 );
+};
+
+
+
+class ConjectureGenerator : public QuantifiersModule
+{
+  friend class OpArgIndex;
+  friend class PatGen;
+  friend class PatternGenEqc;
+  friend class PatternGen;
+  friend class SubsEqcIndex;
+  friend class TermGenerator;
+  friend class TermGenEnv;
+  typedef context::CDChunkList<Node> NodeList;
+  typedef context::CDHashMap< Node, Node, NodeHashFunction > NodeMap;
+  typedef context::CDHashMap< Node, bool, NodeHashFunction > BoolMap;
+//this class maintains a congruence closure for *universal* facts
+private:
+  //notification class for equality engine
+  class NotifyClass : public eq::EqualityEngineNotify {
+    ConjectureGenerator& d_sg;
+  public:
+    NotifyClass(ConjectureGenerator& sg): d_sg(sg) {}
+    bool eqNotifyTriggerEquality(TNode equality, bool value) { return true; }
+    bool eqNotifyTriggerPredicate(TNode predicate, bool value) { return true; }
+    bool eqNotifyTriggerTermEquality(TheoryId tag, TNode t1, TNode t2, bool value) { return true; }
+    void eqNotifyConstantTermMerge(TNode t1, TNode t2) { }
+    void eqNotifyNewClass(TNode t) { d_sg.eqNotifyNewClass(t); }
+    void eqNotifyPreMerge(TNode t1, TNode t2) { d_sg.eqNotifyPreMerge(t1, t2); }
+    void eqNotifyPostMerge(TNode t1, TNode t2) { d_sg.eqNotifyPostMerge(t1, t2); }
+    void eqNotifyDisequal(TNode t1, TNode t2, TNode reason) {d_sg.eqNotifyDisequal(t1, t2, reason); }
+  };/* class ConjectureGenerator::NotifyClass */
+  /** The notify class */
+  NotifyClass d_notify;
+  class EqcInfo{
+  public:
+    EqcInfo( context::Context* c );
+    //representative
+    context::CDO< Node > d_rep;
+  };
+  /** get or make eqc info */
+  EqcInfo* getOrMakeEqcInfo( TNode n, bool doMake = false );
+  /** (universal) equaltity engine */
+  eq::EqualityEngine d_uequalityEngine;
+  /** pending adds */
+  std::vector< Node > d_upendingAdds;
+  /** relevant terms */
+  std::map< Node, bool > d_urelevant_terms;
+  /** information necessary for equivalence classes */
+  std::map< Node, EqcInfo* > d_eqc_info;
+  /** called when a new equivalance class is created */
+  void eqNotifyNewClass(TNode t);
+  /** called when two equivalance classes will merge */
+  void eqNotifyPreMerge(TNode t1, TNode t2);
+  /** called when two equivalance classes have merged */
+  void eqNotifyPostMerge(TNode t1, TNode t2);
+  /** called when two equivalence classes are made disequal */
+  void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);
+  /** are universal equal */
+  bool areUniversalEqual( TNode n1, TNode n2 );
+  /** are universal disequal */
+  bool areUniversalDisequal( TNode n1, TNode n2 );
+  /** get universal representative */
+  TNode getUniversalRepresentative( TNode n, bool add = false );
+  /** set relevant */
+  void setUniversalRelevant( TNode n );
+  /** ordering for universal terms */
+  bool isUniversalLessThan( TNode rt1, TNode rt2 );
+
+  /** the nodes we have reported as canonical representative */
+  std::vector< TNode > d_ue_canon;
+  /** is reported canon */
+  bool isReportedCanon( TNode n );
+  /** mark that term has been reported as canonical rep */
+  void markReportedCanon( TNode n );
+
+private:  //information regarding the conjectures
+  /** list of all conjectures */
+  std::vector< Node > d_conjectures;
+  /** list of all waiting conjectures */
+  std::vector< Node > d_waiting_conjectures_lhs;
+  std::vector< Node > d_waiting_conjectures_rhs;
+  std::vector< int > d_waiting_conjectures_score;
+  /** map of currently considered equality conjectures */
+  std::map< Node, std::vector< Node > > d_waiting_conjectures;
+  /** map of equality conjectures */
+  std::map< Node, std::vector< Node > > d_eq_conjectures;
+  /** currently existing conjectures in equality engine */
+  BoolMap d_ee_conjectures;
+  /** conjecture index */
+  TheoremIndex d_thm_index;
+private:  //free variable list
+  //free variables
+  std::map< TypeNode, std::vector< Node > > d_free_var;
+  //map from free variable to FV#
+  std::map< TNode, unsigned > d_free_var_num;
+  // get canonical free variable #i of type tn
+  Node getFreeVar( TypeNode tn, unsigned i );
+  // get canonical term, return null if it contains a term apart from handled signature
+  Node getCanonicalTerm( TNode n, std::map< TypeNode, unsigned >& var_count, std::map< TNode, TNode >& subs );
+private:  //information regarding the terms
+  //relevant patterns (the LHS's)
+  std::map< TypeNode, std::vector< Node > > d_rel_patterns;
+  //total number of unique variables
+  std::map< TNode, unsigned > d_rel_pattern_var_sum;
+  //by types
+  PatternTypIndex d_rel_pattern_typ_index;
+  // substitution to ground EQC index
+  std::map< TNode, SubstitutionIndex > d_rel_pattern_subs_index;
+  //patterns (the RHS's)
+  std::map< TypeNode, std::vector< Node > > d_patterns;
+  //patterns to # variables per type
+  std::map< TNode, std::map< TypeNode, unsigned > > d_pattern_var_id;
+  // # duplicated variables
+  std::map< TNode, unsigned > d_pattern_var_duplicate;
+  // is normal pattern?  (variables allocated in canonical way left to right)
+  std::map< TNode, int > d_pattern_is_normal;
+  std::map< TNode, int > d_pattern_is_relevant;
+  // patterns to a count of # operators (variables and functions)
+  std::map< TNode, std::map< TNode, unsigned > > d_pattern_fun_id;
+  // term size
+  std::map< TNode, unsigned > d_pattern_fun_sum;
+  // collect functions
+  unsigned collectFunctions( TNode opat, TNode pat, std::map< TNode, unsigned >& funcs,
+                             std::map< TypeNode, unsigned >& mnvn, std::map< TypeNode, unsigned >& mxvn );
+  // add pattern
+  void registerPattern( Node pat, TypeNode tpat );
+private: //for debugging
+  std::map< TNode, unsigned > d_em;
+  unsigned d_conj_count;
+public:
+  //term generation environment
+  TermGenEnv d_tge;
+  //consider term canon
+  bool considerTermCanon( Node ln, bool genRelevant );
+public:  //for generalization
+  //generalizations
+  bool isGeneralization( TNode patg, TNode pat ) {
+    std::map< TNode, TNode > subs;
+    return isGeneralization( patg, pat, subs );
+  }
+  bool isGeneralization( TNode patg, TNode pat, std::map< TNode, TNode >& subs );
+  // get generalization depth
+  int calculateGeneralizationDepth( TNode n, std::vector< TNode >& fv );
+private:
+  //predicate for type
+  std::map< TypeNode, Node > d_typ_pred;
+  //get predicate for type
+  Node getPredicateForType( TypeNode tn );
+  //
+  void getEnumerateUfTerm( Node n, unsigned num, std::vector< Node >& terms );
+  //
+  void getEnumeratePredUfTerm( Node n, unsigned num, std::vector< Node >& terms );
+  // uf operators enumerated
+  std::map< Node, bool > d_uf_enum;
+public:  //for property enumeration
+  //process this candidate conjecture
+  void processCandidateConjecture( TNode lhs, TNode rhs, unsigned lhs_depth, unsigned rhs_depth );
+  //whether it should be considered, negative : no, positive returns score
+  int considerCandidateConjecture( TNode lhs, TNode rhs );
+  //notified of a substitution
+  bool notifySubstitution( TNode glhs, std::map< TNode, TNode >& subs, TNode rhs );
+  //confirmation count
+  unsigned d_subs_confirmCount;
+  //individual witnesses (for range)
+  std::vector< TNode > d_subs_confirmWitnessRange;
+  //individual witnesses (for domain)
+  std::map< TNode, std::vector< TNode > > d_subs_confirmWitnessDomain;
+  //number of ground substitutions whose equality is unknown
+  unsigned d_subs_unkCount;
+private:  //information about ground equivalence classes
+  TNode d_bool_eqc[2];
+  std::map< TNode, Node > d_ground_eqc_map;
+  std::vector< TNode > d_ground_terms;
+  //operator independent term index
+  std::map< TNode, OpArgIndex > d_op_arg_index;
+  //is handled term
+  bool isHandledTerm( TNode n );
+  Node getGroundEqc( TNode r );
+  bool isGroundEqc( TNode r );
+  bool isGroundTerm( TNode n );
+  //has enumerated UF
+  bool hasEnumeratedUf( Node n );
+  // count of full effort checks
+  unsigned d_fullEffortCount;
+  // has added lemma
+  bool d_hasAddedLemma;
+  //flush the waiting conjectures
+  unsigned flushWaitingConjectures( unsigned& addedLemmas, int ldepth, int rdepth );
+public:
+  ConjectureGenerator( QuantifiersEngine * qe, context::Context* c );
+  ~ConjectureGenerator() throw() {}
+  /* needs check */
+  bool needsCheck( Theory::Effort e );
+  /* reset at a round */
+  void reset_round( Theory::Effort e );
+  /* Call during quantifier engine's check */
+  void check( Theory::Effort e, unsigned quant_e );
+  /* Called for new quantifiers */
+  void registerQuantifier( Node q );
+  void assertNode( Node n );
+  /** Identify this module (for debugging, dynamic configuration, etc..) */
+  std::string identify() const { return "ConjectureGenerator"; }
+//options
+private:
+  bool optReqDistinctVarPatterns();
+  bool optFilterUnknown();
+  int optFilterScoreThreshold();
+  unsigned optFullCheckFrequency();
+  unsigned optFullCheckConjectures();
+
+  bool optStatsOnly();
+};
+
+
+}
+}
+}
+
+#endif
index d465df4c0acea1c1ef5d16e914167ec48f61f064..18bffe9082114c1918b962a353a129420a04638b 100644 (file)
-/*********************                                                        */\r
-/*! \file quant_conflict_find.cpp\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief quant conflict find class\r
- **\r
- **/\r
-\r
-#include <vector>\r
-\r
-#include "theory/quantifiers/quant_conflict_find.h"\r
-#include "theory/quantifiers/quant_util.h"\r
-#include "theory/theory_engine.h"\r
-#include "theory/quantifiers/options.h"\r
-#include "theory/quantifiers/term_database.h"\r
-#include "theory/quantifiers/trigger.h"\r
-\r
-using namespace CVC4;\r
-using namespace CVC4::kind;\r
-using namespace CVC4::theory;\r
-using namespace CVC4::theory::quantifiers;\r
-using namespace std;\r
-\r
-namespace CVC4 {\r
-\r
-\r
-\r
-void QuantInfo::initialize( Node q, Node qn ) {\r
-  d_q = q;\r
-  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
-    d_match.push_back( TNode::null() );\r
-    d_match_term.push_back( TNode::null() );\r
-  }\r
-\r
-  //register the variables\r
-  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){\r
-    d_var_num[q[0][i]] = i;\r
-    d_vars.push_back( q[0][i] );\r
-    d_var_types.push_back( q[0][i].getType() );\r
-  }\r
-\r
-  registerNode( qn, true, true );\r
-\r
-\r
-  Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;\r
-  d_mg = new MatchGen( this, qn );\r
-\r
-  if( d_mg->isValid() ){\r
-    /*\r
-    for( unsigned j=0; j<q[0].getNumChildren(); j++ ){\r
-      if( d_inMatchConstraint.find( q[0][j] )==d_inMatchConstraint.end() ){\r
-        Trace("qcf-invalid") << "QCF invalid : variable " << q[0][j] << " does not exist in a matching constraint." << std::endl;\r
-        d_mg->setInvalid();\r
-        break;\r
-      }\r
-    }\r
-    */\r
-    if( d_mg->isValid() ){\r
-      for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){\r
-        if( d_vars[j].getKind()!=BOUND_VARIABLE ){\r
-          d_var_mg[j] = NULL;\r
-          bool is_tsym = false;\r
-          if( !MatchGen::isHandledUfTerm( d_vars[j] ) && d_vars[j].getKind()!=ITE ){\r
-            is_tsym = true;\r
-            d_tsym_vars.push_back( j );\r
-          }\r
-          if( !is_tsym || options::qcfTConstraint() ){\r
-            d_var_mg[j] = new MatchGen( this, d_vars[j], true );\r
-          }\r
-          if( !d_var_mg[j] || !d_var_mg[j]->isValid() ){\r
-            Trace("qcf-invalid") << "QCF invalid : cannot match for " << d_vars[j] << std::endl;\r
-            d_mg->setInvalid();\r
-            break;\r
-          }else{\r
-            std::vector< int > bvars;\r
-            d_var_mg[j]->determineVariableOrder( this, bvars );\r
-          }\r
-        }\r
-      }\r
-      if( d_mg->isValid() ){\r
-        std::vector< int > bvars;\r
-        d_mg->determineVariableOrder( this, bvars );\r
-      }\r
-    }\r
-  }else{\r
-    Trace("qcf-invalid") << "QCF invalid : body of formula cannot be processed." << std::endl;\r
-  }\r
-  Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? "VALID " : "INVALID" ) << " : " << q << std::endl;\r
-}\r
-\r
-void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant ) {\r
-  Trace("qcf-qregister-debug2") << "Register : " << n << std::endl;\r
-  if( n.getKind()==FORALL ){\r
-    registerNode( n[1], hasPol, pol, true );\r
-  }else{\r
-    if( !MatchGen::isHandledBoolConnective( n ) ){\r
-      if( n.hasBoundVar() ){\r
-        //literals\r
-        if( n.getKind()==EQUAL ){\r
-          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-            flatten( n[i], beneathQuant );\r
-          }\r
-        }else if( MatchGen::isHandledUfTerm( n ) ){\r
-          flatten( n, beneathQuant );\r
-        }else if( n.getKind()==ITE ){\r
-          for( unsigned i=1; i<=2; i++ ){\r
-            flatten( n[i], beneathQuant );\r
-          }\r
-          registerNode( n[0], false, pol, beneathQuant );\r
-        }else if( options::qcfTConstraint() ){\r
-          //a theory-specific predicate\r
-          for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-            flatten( n[i], beneathQuant );\r
-          }\r
-        }\r
-      }\r
-    }else{\r
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-        bool newHasPol;\r
-        bool newPol;\r
-        QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );\r
-        //QcfNode * qcfc = new QcfNode( d_c );\r
-        //qcfc->d_parent = qcf;\r
-        //qcf->d_child[i] = qcfc;\r
-        registerNode( n[i], newHasPol, newPol, beneathQuant );\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-void QuantInfo::flatten( Node n, bool beneathQuant ) {\r
-  Trace("qcf-qregister-debug2") << "Flatten : " << n << std::endl;\r
-  if( n.hasBoundVar() ){\r
-    if( n.getKind()==BOUND_VARIABLE ){\r
-      d_inMatchConstraint[n] = true;\r
-    }\r
-    //if( MatchGen::isHandledUfTerm( n ) || n.getKind()==ITE ){\r
-    if( d_var_num.find( n )==d_var_num.end() ){\r
-      Trace("qcf-qregister-debug2") << "Add FLATTEN VAR : " << n << std::endl;\r
-      d_var_num[n] = d_vars.size();\r
-      d_vars.push_back( n );\r
-      d_var_types.push_back( n.getType() );\r
-      d_match.push_back( TNode::null() );\r
-      d_match_term.push_back( TNode::null() );\r
-      if( n.getKind()==ITE ){\r
-        registerNode( n, false, false );\r
-      }else{\r
-        for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-          flatten( n[i], beneathQuant );\r
-        }\r
-      }\r
-    }else{\r
-      Trace("qcf-qregister-debug2") << "...already processed" << std::endl;\r
-    }\r
-  }else{\r
-    Trace("qcf-qregister-debug2") << "...is ground." << std::endl;\r
-  }\r
-}\r
-\r
-\r
-void QuantInfo::reset_round( QuantConflictFind * p ) {\r
-  for( unsigned i=0; i<d_match.size(); i++ ){\r
-    d_match[i] = TNode::null();\r
-    d_match_term[i] = TNode::null();\r
-  }\r
-  d_curr_var_deq.clear();\r
-  d_tconstraints.clear();\r
-  //add built-in variable constraints\r
-  for( unsigned r=0; r<2; r++ ){\r
-    for( std::map< int, std::vector< Node > >::iterator it = d_var_constraint[r].begin();\r
-         it != d_var_constraint[r].end(); ++it ){\r
-      for( unsigned j=0; j<it->second.size(); j++ ){\r
-        Node rr = it->second[j];\r
-        if( !isVar( rr ) ){\r
-          rr = p->getRepresentative( rr );\r
-        }\r
-        if( addConstraint( p, it->first, rr, r==0 )==-1 ){\r
-          d_var_constraint[0].clear();\r
-          d_var_constraint[1].clear();\r
-          //quantified formula is actually equivalent to true\r
-          Trace("qcf-qregister") << "Quantifier is equivalent to true!!!" << std::endl;\r
-          d_mg->d_children.clear();\r
-          d_mg->d_n = NodeManager::currentNM()->mkConst( true );\r
-          d_mg->d_type = MatchGen::typ_ground;\r
-          return;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  d_mg->reset_round( p );\r
-  for( std::map< int, MatchGen * >::iterator it = d_var_mg.begin(); it != d_var_mg.end(); ++it ){\r
-    it->second->reset_round( p );\r
-  }\r
-  //now, reset for matching\r
-  d_mg->reset( p, false, this );\r
-}\r
-\r
-int QuantInfo::getCurrentRepVar( int v ) {\r
-  if( v!=-1 && !d_match[v].isNull() ){\r
-    int vn = getVarNum( d_match[v] );\r
-    if( vn!=-1 ){\r
-      //int vr = getCurrentRepVar( vn );\r
-      //d_match[v] = d_vars[vr];\r
-      //return vr;\r
-      return getCurrentRepVar( vn );\r
-    }\r
-  }\r
-  return v;\r
-}\r
-\r
-TNode QuantInfo::getCurrentValue( TNode n ) {\r
-  int v = getVarNum( n );\r
-  if( v==-1 ){\r
-    return n;\r
-  }else{\r
-    if( d_match[v].isNull() ){\r
-      return n;\r
-    }else{\r
-      Assert( getVarNum( d_match[v] )!=v );\r
-      return getCurrentValue( d_match[v] );\r
-    }\r
-  }\r
-}\r
-\r
-TNode QuantInfo::getCurrentExpValue( TNode n ) {\r
-  int v = getVarNum( n );\r
-  if( v==-1 ){\r
-    return n;\r
-  }else{\r
-    if( d_match[v].isNull() ){\r
-      return n;\r
-    }else{\r
-      Assert( getVarNum( d_match[v] )!=v );\r
-      if( d_match_term[v].isNull() ){\r
-        return getCurrentValue( d_match[v] );\r
-      }else{\r
-        return d_match_term[v];\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-bool QuantInfo::getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq ) {\r
-  //check disequalities\r
-  std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );\r
-  if( itd!=d_curr_var_deq.end() ){\r
-    for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
-      Node cv = getCurrentValue( it->first );\r
-      Debug("qcf-ccbe") << "compare " << cv << " " << n << std::endl;\r
-      if( cv==n ){\r
-        return false;\r
-      }else if( chDiseq && !isVar( n ) && !isVar( cv ) ){\r
-        //they must actually be disequal if we are looking for conflicts\r
-        if( !p->areDisequal( n, cv ) ){\r
-          //TODO : check for entailed disequal\r
-\r
-          return false;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return true;\r
-}\r
-\r
-int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity ) {\r
-  v = getCurrentRepVar( v );\r
-  int vn = getVarNum( n );\r
-  vn = vn==-1 ? -1 : getCurrentRepVar( vn );\r
-  n = getCurrentValue( n );\r
-  return addConstraint( p, v, n, vn, polarity, false );\r
-}\r
-\r
-int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove ) {\r
-  //for handling equalities between variables, and disequalities involving variables\r
-  Debug("qcf-match-debug") << "- " << (doRemove ? "un" : "" ) << "constrain : " << v << " -> " << n << " (cv=" << getCurrentValue( n ) << ")";\r
-  Debug("qcf-match-debug") << ", (vn=" << vn << "), polarity = " << polarity << std::endl;\r
-  Assert( doRemove || n==getCurrentValue( n ) );\r
-  Assert( doRemove || v==getCurrentRepVar( v ) );\r
-  Assert( doRemove || vn==getCurrentRepVar( getVarNum( n ) ) );\r
-  if( polarity ){\r
-    if( vn!=v ){\r
-      if( doRemove ){\r
-        if( vn!=-1 ){\r
-          //if set to this in the opposite direction, clean up opposite instead\r
-          //          std::map< int, TNode >::iterator itmn = d_match.find( vn );\r
-          if( d_match[vn]==d_vars[v] ){\r
-            return addConstraint( p, vn, d_vars[v], v, true, true );\r
-          }else{\r
-            //unsetting variables equal\r
-            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( vn );\r
-            if( itd!=d_curr_var_deq.end() ){\r
-              //remove disequalities owned by this\r
-              std::vector< TNode > remDeq;\r
-              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
-                if( it->second==v ){\r
-                  remDeq.push_back( it->first );\r
-                }\r
-              }\r
-              for( unsigned i=0; i<remDeq.size(); i++ ){\r
-                d_curr_var_deq[vn].erase( remDeq[i] );\r
-              }\r
-            }\r
-          }\r
-        }\r
-        d_match[v] = TNode::null();\r
-        return 1;\r
-      }else{\r
-        //std::map< int, TNode >::iterator itm = d_match.find( v );\r
-\r
-        if( vn!=-1 ){\r
-          Debug("qcf-match-debug") << "  ...Variable bound to variable" << std::endl;\r
-          //std::map< int, TNode >::iterator itmn = d_match.find( vn );\r
-          if( d_match[v].isNull() ){\r
-            //setting variables equal\r
-            bool alreadySet = false;\r
-            if( !d_match[vn].isNull() ){\r
-              alreadySet = true;\r
-              Assert( !isVar( d_match[vn] ) );\r
-            }\r
-\r
-            //copy or check disequalities\r
-            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );\r
-            if( itd!=d_curr_var_deq.end() ){\r
-              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){\r
-                Node dv = getCurrentValue( it->first );\r
-                if( !alreadySet ){\r
-                  if( d_curr_var_deq[vn].find( dv )==d_curr_var_deq[vn].end() ){\r
-                    d_curr_var_deq[vn][dv] = v;\r
-                  }\r
-                }else{\r
-                  if( !p->areMatchDisequal( d_match[vn], dv ) ){\r
-                    Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
-                    return -1;\r
-                  }\r
-                }\r
-              }\r
-            }\r
-            if( alreadySet ){\r
-              n = getCurrentValue( n );\r
-            }\r
-          }else{\r
-            if( d_match[vn].isNull() ){\r
-              Debug("qcf-match-debug") << " ...Reverse direction" << std::endl;\r
-              //set the opposite direction\r
-              return addConstraint( p, vn, d_vars[v], v, true, false );\r
-            }else{\r
-              Debug("qcf-match-debug") << "  -> Both variables bound, compare" << std::endl;\r
-              //are they currently equal\r
-              return p->areMatchEqual( d_match[v], d_match[vn] ) ? 0 : -1;\r
-            }\r
-          }\r
-        }else{\r
-          Debug("qcf-match-debug") << "  ...Variable bound to ground" << std::endl;\r
-          if( d_match[v].isNull() ){\r
-          }else{\r
-            //compare ground values\r
-            Debug("qcf-match-debug") << "  -> Ground value, compare " << d_match[v] << " "<< n << std::endl;\r
-            return p->areMatchEqual( d_match[v], n ) ? 0 : -1;\r
-          }\r
-        }\r
-        if( setMatch( p, v, n ) ){\r
-          Debug("qcf-match-debug") << "  -> success" << std::endl;\r
-          return 1;\r
-        }else{\r
-          Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
-          return -1;\r
-        }\r
-      }\r
-    }else{\r
-      Debug("qcf-match-debug") << "  -> redundant, variable identity" << std::endl;\r
-      return 0;\r
-    }\r
-  }else{\r
-    if( vn==v ){\r
-      Debug("qcf-match-debug") << "  -> fail, variable identity" << std::endl;\r
-      return -1;\r
-    }else{\r
-      if( doRemove ){\r
-        Assert( d_curr_var_deq[v].find( n )!=d_curr_var_deq[v].end() );\r
-        d_curr_var_deq[v].erase( n );\r
-        return 1;\r
-      }else{\r
-        if( d_curr_var_deq[v].find( n )==d_curr_var_deq[v].end() ){\r
-          //check if it respects equality\r
-          //std::map< int, TNode >::iterator itm = d_match.find( v );\r
-          if( !d_match[v].isNull() ){\r
-            TNode nv = getCurrentValue( n );\r
-            if( !p->areMatchDisequal( nv, d_match[v] ) ){\r
-              Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;\r
-              return -1;\r
-            }\r
-          }\r
-          d_curr_var_deq[v][n] = v;\r
-          Debug("qcf-match-debug") << "  -> success" << std::endl;\r
-          return 1;\r
-        }else{\r
-          Debug("qcf-match-debug") << "  -> redundant disequality" << std::endl;\r
-          return 0;\r
-        }\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-bool QuantInfo::isConstrainedVar( int v ) {\r
-  if( d_curr_var_deq.find( v )!=d_curr_var_deq.end() && !d_curr_var_deq[v].empty() ){\r
-    return true;\r
-  }else{\r
-    Node vv = getVar( v );\r
-    //for( std::map< int, TNode >::iterator it = d_match.begin(); it != d_match.end(); ++it ){\r
-    for( unsigned i=0; i<d_match.size(); i++ ){\r
-      if( d_match[i]==vv ){\r
-        return true;\r
-      }\r
-    }\r
-    for( std::map< int, std::map< TNode, int > >::iterator it = d_curr_var_deq.begin(); it != d_curr_var_deq.end(); ++it ){\r
-      for( std::map< TNode, int >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){\r
-        if( it2->first==vv ){\r
-          return true;\r
-        }\r
-      }\r
-    }\r
-    return false;\r
-  }\r
-}\r
-\r
-bool QuantInfo::setMatch( QuantConflictFind * p, int v, TNode n ) {\r
-  if( getCurrentCanBeEqual( p, v, n ) ){\r
-    Debug("qcf-match-debug") << "-- bind : " << v << " -> " << n << ", checked " <<  d_curr_var_deq[v].size() << " disequalities" << std::endl;\r
-    d_match[v] = n;\r
-    return true;\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-bool QuantInfo::isMatchSpurious( QuantConflictFind * p ) {\r
-  for( int i=0; i<getNumVars(); i++ ){\r
-    //std::map< int, TNode >::iterator it = d_match.find( i );\r
-    if( !d_match[i].isNull() ){\r
-      if( !getCurrentCanBeEqual( p, i, d_match[i], p->d_effort==QuantConflictFind::effort_conflict ) ){\r
-        return true;\r
-      }\r
-    }\r
-  }\r
-  return false;\r
-}\r
-\r
-bool QuantInfo::isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms ) {\r
-  if( !d_tconstraints.empty() ){\r
-    //check constraints\r
-    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){\r
-      //apply substitution to the tconstraint\r
-      Node cons = it->first.substitute( p->getTermDatabase()->d_vars[d_q].begin(),\r
-                                        p->getTermDatabase()->d_vars[d_q].end(),\r
-                                        terms.begin(), terms.end() );\r
-      cons = it->second ? cons : cons.negate();\r
-      if( !entailmentTest( p, cons, p->d_effort==QuantConflictFind::effort_conflict ) ){\r
-        return true;\r
-      }\r
-    }\r
-  }\r
-  return false;\r
-}\r
-\r
-bool QuantInfo::entailmentTest( QuantConflictFind * p, Node lit, bool chEnt ) {\r
-  Trace("qcf-tconstraint-debug") << "Check : " << lit << std::endl;\r
-  Node rew = Rewriter::rewrite( lit );\r
-  if( rew==p->d_false ){\r
-    Trace("qcf-tconstraint-debug") << "...constraint " << lit << " is disentailed (rewrites to false)." << std::endl;\r
-    return false;\r
-  }else if( rew!=p->d_true ){\r
-    //if checking for conflicts, we must be sure that the constraint is entailed\r
-    if( chEnt ){\r
-      //check if it is entailed\r
-      Trace("qcf-tconstraint-debug") << "Check entailment of " << rew << "..." << std::endl;\r
-      std::pair<bool, Node> et = p->getQuantifiersEngine()->getTheoryEngine()->entailmentCheck(THEORY_OF_TYPE_BASED, rew );\r
-      ++(p->d_statistics.d_entailment_checks);\r
-      Trace("qcf-tconstraint-debug") << "ET result : " << et.first << " " << et.second << std::endl;\r
-      if( !et.first ){\r
-        Trace("qcf-tconstraint-debug") << "...cannot show entailment of " << rew << "." << std::endl;\r
-        return false;\r
-      }else{\r
-        return true;\r
-      }\r
-    }else{\r
-      Trace("qcf-tconstraint-debug") << "...does not need to be entailed." << std::endl;\r
-      return true;\r
-    }\r
-  }else{\r
-    Trace("qcf-tconstraint-debug") << "...rewrites to true." << std::endl;\r
-    return true;\r
-  }\r
-}\r
-\r
-bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue ) {\r
-  //assign values for variables that were unassigned (usually not necessary, but handles corner cases)\r
-  bool doFail = false;\r
-  bool success = true;\r
-  if( doContinue ){\r
-    doFail = true;\r
-    success = false;\r
-  }else{\r
-    //solve for interpreted symbol matches\r
-    //   this breaks the invariant that all introduced constraints are over existing terms\r
-    for( int i=(int)(d_tsym_vars.size()-1); i>=0; i-- ){\r
-      int index = d_tsym_vars[i];\r
-      TNode v = getCurrentValue( d_vars[index] );\r
-      int slv_v = -1;\r
-      if( v==d_vars[index] ){\r
-        slv_v = index;\r
-      }\r
-      Trace("qcf-tconstraint-debug") << "Solve " << d_vars[index] << " = " << v << " " << d_vars[index].getKind() << std::endl;\r
-      if( d_vars[index].getKind()==PLUS || d_vars[index].getKind()==MULT ){\r
-        Kind k = d_vars[index].getKind();\r
-        std::vector< TNode > children;\r
-        for( unsigned j=0; j<d_vars[index].getNumChildren(); j++ ){\r
-          int vn = getVarNum( d_vars[index][j] );\r
-          if( vn!=-1 ){\r
-            TNode vv = getCurrentValue( d_vars[index][j] );\r
-            if( vv==d_vars[index][j] ){\r
-              //we will assign this\r
-              if( slv_v==-1 ){\r
-                Trace("qcf-tconstraint-debug") << "...will solve for var #" << vn << std::endl;\r
-                slv_v = vn;\r
-                if( p->d_effort!=QuantConflictFind::effort_conflict ){\r
-                  break;\r
-                }\r
-              }else{\r
-                Node z = p->getZero( k );\r
-                if( !z.isNull() ){\r
-                  Trace("qcf-tconstraint-debug") << "...set " << d_vars[vn] << " = " << z << std::endl;\r
-                  assigned.push_back( vn );\r
-                  if( !setMatch( p, vn, z ) ){\r
-                    success = false;\r
-                    break;\r
-                  }\r
-                }\r
-              }\r
-            }else{\r
-              Trace("qcf-tconstraint-debug") << "...sum value " << vv << std::endl;\r
-              children.push_back( vv );\r
-            }\r
-          }else{\r
-            Trace("qcf-tconstraint-debug") << "...sum " << d_vars[index][j] << std::endl;\r
-            children.push_back( d_vars[index][j] );\r
-          }\r
-        }\r
-        if( success ){\r
-          if( slv_v!=-1 ){\r
-            Node lhs;\r
-            if( children.empty() ){\r
-              lhs = p->getZero( k );\r
-            }else if( children.size()==1 ){\r
-              lhs = children[0];\r
-            }else{\r
-              lhs = NodeManager::currentNM()->mkNode( k, children );\r
-            }\r
-            Node sum;\r
-            if( v==d_vars[index] ){\r
-              sum = lhs;\r
-            }else{\r
-              if( p->d_effort==QuantConflictFind::effort_conflict ){\r
-                Kind kn = k;\r
-                if( d_vars[index].getKind()==PLUS ){\r
-                  kn = MINUS;\r
-                }\r
-                if( kn!=k ){\r
-                  sum = NodeManager::currentNM()->mkNode( kn, v, lhs );\r
-                }\r
-              }\r
-            }\r
-            if( !sum.isNull() ){\r
-              assigned.push_back( slv_v );\r
-              Trace("qcf-tconstraint-debug") << "...set " << d_vars[slv_v] << " = " << sum << std::endl;\r
-              if( !setMatch( p, slv_v, sum ) ){\r
-                success = false;\r
-              }\r
-              p->d_tempCache.push_back( sum );\r
-            }\r
-          }else{\r
-            //must show that constraint is met\r
-            Node sum = NodeManager::currentNM()->mkNode( k, children );\r
-            Node eq = sum.eqNode( v );\r
-            if( !entailmentTest( p, eq ) ){\r
-              success = false;\r
-            }\r
-            p->d_tempCache.push_back( sum );\r
-          }\r
-        }\r
-      }\r
-\r
-      if( !success ){\r
-        break;\r
-      }\r
-    }\r
-    if( success ){\r
-      //check what is left to assign\r
-      d_unassigned.clear();\r
-      d_unassigned_tn.clear();\r
-      std::vector< int > unassigned[2];\r
-      std::vector< TypeNode > unassigned_tn[2];\r
-      for( int i=0; i<getNumVars(); i++ ){\r
-        if( d_match[i].isNull() ){\r
-          int rindex = d_var_mg.find( i )==d_var_mg.end() ? 1 : 0;\r
-          unassigned[rindex].push_back( i );\r
-          unassigned_tn[rindex].push_back( getVar( i ).getType() );\r
-          assigned.push_back( i );\r
-        }\r
-      }\r
-      d_unassigned_nvar = unassigned[0].size();\r
-      for( unsigned i=0; i<2; i++ ){\r
-        d_unassigned.insert( d_unassigned.end(), unassigned[i].begin(), unassigned[i].end() );\r
-        d_unassigned_tn.insert( d_unassigned_tn.end(), unassigned_tn[i].begin(), unassigned_tn[i].end() );\r
-      }\r
-      d_una_eqc_count.clear();\r
-      d_una_index = 0;\r
-    }\r
-  }\r
-\r
-  if( !d_unassigned.empty() && ( success || doContinue ) ){\r
-    Trace("qcf-check") << "Assign to unassigned..." << std::endl;\r
-    do {\r
-      if( doFail ){\r
-        Trace("qcf-check-unassign") << "Failure, try again..." << std::endl;\r
-      }\r
-      bool invalidMatch = false;\r
-      while( ( d_una_index>=0 && (int)d_una_index<(int)d_unassigned.size() ) || invalidMatch || doFail ){\r
-        invalidMatch = false;\r
-        if( !doFail && d_una_index==(int)d_una_eqc_count.size() ){\r
-          //check if it has now been assigned\r
-          if( d_una_index<d_unassigned_nvar ){\r
-            if( !isConstrainedVar( d_unassigned[d_una_index] ) ){\r
-              d_una_eqc_count.push_back( -1 );\r
-            }else{\r
-              d_var_mg[ d_unassigned[d_una_index] ]->reset( p, true, this );\r
-              d_una_eqc_count.push_back( 0 );\r
-            }\r
-          }else{\r
-            d_una_eqc_count.push_back( 0 );\r
-          }\r
-        }else{\r
-          bool failed = false;\r
-          if( !doFail ){\r
-            if( d_una_index<d_unassigned_nvar ){\r
-              if( !isConstrainedVar( d_unassigned[d_una_index] ) ){\r
-                Trace("qcf-check-unassign") << "Succeeded, variable unconstrained at " << d_una_index << std::endl;\r
-                d_una_index++;\r
-              }else if( d_var_mg[d_unassigned[d_una_index]]->getNextMatch( p, this ) ){\r
-                Trace("qcf-check-unassign") << "Succeeded match with mg at " << d_una_index << std::endl;\r
-                d_una_index++;\r
-              }else{\r
-                failed = true;\r
-                Trace("qcf-check-unassign") << "Failed match with mg at " << d_una_index << std::endl;\r
-              }\r
-            }else{\r
-              Assert( doFail || d_una_index==(int)d_una_eqc_count.size()-1 );\r
-              if( d_una_eqc_count[d_una_index]<(int)p->d_eqcs[d_unassigned_tn[d_una_index]].size() ){\r
-                int currIndex = d_una_eqc_count[d_una_index];\r
-                d_una_eqc_count[d_una_index]++;\r
-                Trace("qcf-check-unassign") << d_unassigned[d_una_index] << "->" << p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] << std::endl;\r
-                if( setMatch( p, d_unassigned[d_una_index], p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] ) ){\r
-                  d_match_term[d_unassigned[d_una_index]] = TNode::null();\r
-                  Trace("qcf-check-unassign") << "Succeeded match " << d_una_index << std::endl;\r
-                  d_una_index++;\r
-                }else{\r
-                  Trace("qcf-check-unassign") << "Failed match " << d_una_index << std::endl;\r
-                  invalidMatch = true;\r
-                }\r
-              }else{\r
-                failed = true;\r
-                Trace("qcf-check-unassign") << "No more matches " << d_una_index << std::endl;\r
-              }\r
-            }\r
-          }\r
-          if( doFail || failed ){\r
-            do{\r
-              if( !doFail ){\r
-                d_una_eqc_count.pop_back();\r
-              }else{\r
-                doFail = false;\r
-              }\r
-              d_una_index--;\r
-            }while( d_una_index>=0 && d_una_eqc_count[d_una_index]==-1 );\r
-          }\r
-        }\r
-      }\r
-      success = d_una_index>=0;\r
-      if( success ){\r
-        doFail = true;\r
-        Trace("qcf-check-unassign") << "  Try: " << std::endl;\r
-        for( unsigned i=0; i<d_unassigned.size(); i++ ){\r
-          int ui = d_unassigned[i];\r
-          if( !d_match[ui].isNull() ){\r
-            Trace("qcf-check-unassign") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;\r
-          }\r
-        }\r
-      }\r
-    }while( success && isMatchSpurious( p ) );\r
-  }\r
-  if( success ){\r
-    for( unsigned i=0; i<d_unassigned.size(); i++ ){\r
-      int ui = d_unassigned[i];\r
-      if( !d_match[ui].isNull() ){\r
-        Trace("qcf-check") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;\r
-      }\r
-    }\r
-    return true;\r
-  }else{\r
-    for( unsigned i=0; i<assigned.size(); i++ ){\r
-      d_match[ assigned[i] ] = TNode::null();\r
-    }\r
-    assigned.clear();\r
-    return false;\r
-  }\r
-}\r
-\r
-void QuantInfo::getMatch( std::vector< Node >& terms ){\r
-  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){\r
-    //Node cv = qi->getCurrentValue( qi->d_match[i] );\r
-    int repVar = getCurrentRepVar( i );\r
-    Node cv;\r
-    //std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );\r
-    if( !d_match_term[repVar].isNull() ){\r
-      cv = d_match_term[repVar];\r
-    }else{\r
-      cv = d_match[repVar];\r
-    }\r
-    Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << d_match[i] << std::endl;\r
-    terms.push_back( cv );\r
-  }\r
-}\r
-\r
-void QuantInfo::revertMatch( std::vector< int >& assigned ) {\r
-  for( unsigned i=0; i<assigned.size(); i++ ){\r
-    d_match[ assigned[i] ] = TNode::null();\r
-  }\r
-}\r
-\r
-void QuantInfo::debugPrintMatch( const char * c ) {\r
-  for( int i=0; i<getNumVars(); i++ ){\r
-    Trace(c) << "  " << d_vars[i] << " -> ";\r
-    if( !d_match[i].isNull() ){\r
-      Trace(c) << d_match[i];\r
-    }else{\r
-      Trace(c) << "(unassigned) ";\r
-    }\r
-    if( !d_curr_var_deq[i].empty() ){\r
-      Trace(c) << ", DEQ{ ";\r
-      for( std::map< TNode, int >::iterator it = d_curr_var_deq[i].begin(); it != d_curr_var_deq[i].end(); ++it ){\r
-        Trace(c) << it->first << " ";\r
-      }\r
-      Trace(c) << "}";\r
-    }\r
-    if( !d_match_term[i].isNull() && d_match_term[i]!=d_match[i] ){\r
-      Trace(c) << ", EXP : " << d_match_term[i];\r
-    }\r
-    Trace(c) <<  std::endl;\r
-  }\r
-  if( !d_tconstraints.empty() ){\r
-    Trace(c) << "ADDITIONAL CONSTRAINTS : " << std::endl;\r
-    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){\r
-      Trace(c) << "   " << it->first << " -> " << it->second << std::endl;\r
-    }\r
-  }\r
-}\r
-\r
-MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar ){\r
-  Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << std::endl;\r
-  std::vector< Node > qni_apps;\r
-  d_qni_size = 0;\r
-  if( isVar ){\r
-    Assert( qi->d_var_num.find( n )!=qi->d_var_num.end() );\r
-    if( n.getKind()==ITE ){\r
-      d_type = typ_ite_var;\r
-      d_type_not = false;\r
-      d_n = n;\r
-      d_children.push_back( MatchGen( qi, d_n[0] ) );\r
-      if( d_children[0].isValid() ){\r
-        d_type = typ_ite_var;\r
-        for( unsigned i=1; i<=2; i++ ){\r
-          Node nn = n.eqNode( n[i] );\r
-          d_children.push_back( MatchGen( qi, nn ) );\r
-          d_children[d_children.size()-1].d_qni_bound_except.push_back( 0 );\r
-          if( !d_children[d_children.size()-1].isValid() ){\r
-            setInvalid();\r
-            break;\r
-          }\r
-        }\r
-      }else{\r
-        d_type = typ_invalid;\r
-      }\r
-    }else{\r
-      d_type = isHandledUfTerm( n ) ? typ_var : typ_tsym;\r
-      d_qni_var_num[0] = qi->getVarNum( n );\r
-      d_qni_size++;\r
-      d_type_not = false;\r
-      d_n = n;\r
-      //Node f = getOperator( n );\r
-      for( unsigned j=0; j<d_n.getNumChildren(); j++ ){\r
-        Node nn = d_n[j];\r
-        Trace("qcf-qregister-debug") << "  " << d_qni_size;\r
-        if( qi->isVar( nn ) ){\r
-          int v = qi->d_var_num[nn];\r
-          Trace("qcf-qregister-debug") << " is var #" << v << std::endl;\r
-          d_qni_var_num[d_qni_size] = v;\r
-          //qi->addFuncParent( v, f, j );\r
-        }else{\r
-          Trace("qcf-qregister-debug") << " is gterm " << nn << std::endl;\r
-          d_qni_gterm[d_qni_size] = nn;\r
-        }\r
-        d_qni_size++;\r
-      }\r
-    }\r
-  }else{\r
-    if( n.hasBoundVar() ){\r
-      d_type_not = false;\r
-      d_n = n;\r
-      if( d_n.getKind()==NOT ){\r
-        d_n = d_n[0];\r
-        d_type_not = !d_type_not;\r
-      }\r
-\r
-      if( isHandledBoolConnective( d_n ) ){\r
-        //non-literals\r
-        d_type = typ_formula;\r
-        for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
-          if( d_n.getKind()!=FORALL || i==1 ){\r
-            d_children.push_back( MatchGen( qi, d_n[i], false ) );\r
-            if( !d_children[d_children.size()-1].isValid() ){\r
-              setInvalid();\r
-              break;\r
-            }\r
-          }\r
-          /*\r
-          else if( isTop && n.getKind()==OR && d_children[d_children.size()-1].d_type==typ_var_eq ){\r
-            Trace("qcf-qregister-debug") << "Remove child, make built-in constraint" << std::endl;\r
-            //if variable equality/disequality at top level, remove immediately\r
-            bool cIsNot = d_children[d_children.size()-1].d_type_not;\r
-            Node cn = d_children[d_children.size()-1].d_n;\r
-            Assert( cn.getKind()==EQUAL );\r
-            Assert( p->d_qinfo[q].isVar( cn[0] ) || p->d_qinfo[q].isVar( cn[1] ) );\r
-            //make it a built-in constraint instead\r
-            for( unsigned i=0; i<2; i++ ){\r
-              if( p->d_qinfo[q].isVar( cn[i] ) ){\r
-                int v = p->d_qinfo[q].getVarNum( cn[i] );\r
-                Node cno = cn[i==0 ? 1 : 0];\r
-                p->d_qinfo[q].d_var_constraint[ cIsNot ? 0 : 1 ][v].push_back( cno );\r
-                break;\r
-              }\r
-            }\r
-            d_children.pop_back();\r
-          }\r
-          */\r
-        }\r
-      }else{\r
-        d_type = typ_invalid;\r
-        //literals\r
-        if( isHandledUfTerm( d_n ) ){\r
-          Assert( qi->isVar( d_n ) );\r
-          d_type = typ_pred;\r
-        }else if( d_n.getKind()==BOUND_VARIABLE ){\r
-          Assert( d_n.getType().isBoolean() );\r
-          d_type = typ_bool_var;\r
-        }else if( d_n.getKind()==EQUAL || options::qcfTConstraint() ){\r
-          for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
-            if( d_n[i].hasBoundVar() ){\r
-              if( !qi->isVar( d_n[i] ) ){\r
-                Trace("qcf-qregister-debug")  << "ERROR : not var " << d_n[i] << std::endl;\r
-              }\r
-              Assert( qi->isVar( d_n[i] ) );\r
-              if( d_n.getKind()!=EQUAL && qi->isVar( d_n[i] ) ){\r
-                d_qni_var_num[i+1] = qi->d_var_num[d_n[i]];\r
-              }\r
-            }else{\r
-              d_qni_gterm[i] = d_n[i];\r
-            }\r
-          }\r
-          d_type = d_n.getKind()==EQUAL ? typ_eq : typ_tconstraint;\r
-          Trace("qcf-tconstraint") << "T-Constraint : " << d_n << std::endl;\r
-        }\r
-      }\r
-    }else{\r
-      //we will just evaluate\r
-      d_n = n;\r
-      d_type = typ_ground;\r
-    }\r
-    //if( d_type!=typ_invalid ){\r
-      //determine an efficient children ordering\r
-      //if( !d_children.empty() ){\r
-        //for( unsigned i=0; i<d_children.size(); i++ ){\r
-        //  d_children_order.push_back( i );\r
-        //}\r
-        //if( !d_n.isNull() && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF ) ){\r
-          //sort based on the type of the constraint : ground comes first, then literals, then others\r
-          //MatchGenSort mgs;\r
-          //mgs.d_mg = this;\r
-          //std::sort( d_children_order.begin(), d_children_order.end(), mgs );\r
-        //}\r
-      //}\r
-    //}\r
-  }\r
-  Trace("qcf-qregister-debug")  << "Done make match gen " << n << ", type = ";\r
-  debugPrintType( "qcf-qregister-debug", d_type, true );\r
-  Trace("qcf-qregister-debug") << std::endl;\r
-  //Assert( d_children.size()==d_children_order.size() );\r
-\r
-}\r
-\r
-void MatchGen::collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ) {\r
-  int v = qi->getVarNum( n );\r
-  if( v!=-1 && std::find( cbvars.begin(), cbvars.end(), v )==cbvars.end() ){\r
-    cbvars.push_back( v );\r
-  }\r
-  for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-    collectBoundVar( qi, n[i], cbvars );\r
-  }\r
-}\r
-\r
-void MatchGen::determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars ) {\r
-  Trace("qcf-qregister-debug") << "Determine variable order " << d_n << std::endl;\r
-  bool isCom = d_type==typ_formula && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF );\r
-  std::map< int, std::vector< int > > c_to_vars;\r
-  std::map< int, std::vector< int > > vars_to_c;\r
-  std::map< int, int > vb_count;\r
-  std::map< int, int > vu_count;\r
-  std::vector< bool > assigned;\r
-  Trace("qcf-qregister-debug") << "Calculate bound variables..." << std::endl;\r
-  for( unsigned i=0; i<d_children.size(); i++ ){\r
-    collectBoundVar( qi, d_children[i].d_n, c_to_vars[i] );\r
-    assigned.push_back( false );\r
-    vb_count[i] = 0;\r
-    vu_count[i] = 0;\r
-    for( unsigned j=0; j<c_to_vars[i].size(); j++ ){\r
-      int v = c_to_vars[i][j];\r
-      vars_to_c[v].push_back( i );\r
-      if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){\r
-        vu_count[i]++;\r
-        if( !isCom ){\r
-          bvars.push_back( v );\r
-        }\r
-      }else{\r
-        vb_count[i]++;\r
-      }\r
-    }\r
-  }\r
-  if( isCom ){\r
-    //children that bind the least number of unbound variables go first\r
-    do {\r
-      int min_score = -1;\r
-      int min_score_index = -1;\r
-      for( unsigned i=0; i<d_children.size(); i++ ){\r
-        if( !assigned[i] ){\r
-          int score = vu_count[i];\r
-          if( min_score==-1 || score<min_score ){\r
-            min_score = score;\r
-            min_score_index = i;\r
-          }\r
-        }\r
-      }\r
-      Trace("qcf-qregister-debug") << "...assign child " << min_score_index << "/" << d_children.size() << std::endl;\r
-      Assert( min_score_index!=-1 );\r
-      //add to children order\r
-      d_children_order.push_back( min_score_index );\r
-      assigned[min_score_index] = true;\r
-      //if( vb_count[min_score_index]==0 ){\r
-      //  d_independent.push_back( min_score_index );\r
-      //}\r
-      //determine order internal to children\r
-      d_children[min_score_index].determineVariableOrder( qi, bvars );\r
-      Trace("qcf-qregister-debug")  << "...bind variables" << std::endl;\r
-      //now, make it a bound variable\r
-      for( unsigned i=0; i<c_to_vars[min_score_index].size(); i++ ){\r
-        int v = c_to_vars[min_score_index][i];\r
-        if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){\r
-          for( unsigned j=0; j<vars_to_c[v].size(); j++ ){\r
-            int vc = vars_to_c[v][j];\r
-            vu_count[vc]--;\r
-            vb_count[vc]++;\r
-          }\r
-          bvars.push_back( v );\r
-        }\r
-      }\r
-      Trace("qcf-qregister-debug") << "...done assign child " << min_score_index << std::endl;\r
-    }while( d_children_order.size()!=d_children.size() );\r
-    Trace("qcf-qregister-debug") << "Done assign variable ordering for " << d_n << std::endl;\r
-  }else{\r
-    for( unsigned i=0; i<d_children.size(); i++ ){\r
-      d_children_order.push_back( i );\r
-      d_children[i].determineVariableOrder( qi, bvars );\r
-    }\r
-  }\r
-}\r
-\r
-\r
-void MatchGen::reset_round( QuantConflictFind * p ) {\r
-  d_wasSet = false;\r
-  for( unsigned i=0; i<d_children.size(); i++ ){\r
-    d_children[i].reset_round( p );\r
-  }\r
-  for( std::map< int, TNode >::iterator it = d_qni_gterm.begin(); it != d_qni_gterm.end(); ++it ){\r
-    d_qni_gterm_rep[it->first] = p->getRepresentative( it->second );\r
-  }\r
-  if( d_type==typ_ground ){\r
-    int e = p->evaluate( d_n );\r
-    if( e==1 ){\r
-      d_ground_eval[0] = p->d_true;\r
-    }else if( e==-1 ){\r
-      d_ground_eval[0] = p->d_false;\r
-    }\r
-  }else if( d_type==typ_eq ){\r
-    for( unsigned i=0; i<d_n.getNumChildren(); i++ ){\r
-      if( !d_n[i].hasBoundVar() ){\r
-        d_ground_eval[i] = p->evaluateTerm( d_n[i] );\r
-      }\r
-    }\r
-  }\r
-  d_qni_bound_cons.clear();\r
-  d_qni_bound_cons_var.clear();\r
-  d_qni_bound.clear();\r
-}\r
-\r
-void MatchGen::reset( QuantConflictFind * p, bool tgt, QuantInfo * qi ) {\r
-  d_tgt = d_type_not ? !tgt : tgt;\r
-  Debug("qcf-match") << "     Reset for : " << d_n << ", type : ";\r
-  debugPrintType( "qcf-match", d_type );\r
-  Debug("qcf-match") << ", tgt = " << d_tgt << ", children = " << d_children.size() << " " << d_children_order.size() << std::endl;\r
-  d_qn.clear();\r
-  d_qni.clear();\r
-  d_qni_bound.clear();\r
-  d_child_counter = -1;\r
-  d_tgt_orig = d_tgt;\r
-\r
-  //set up processing matches\r
-  if( d_type==typ_invalid ){\r
-    //do nothing\r
-  }else if( d_type==typ_ground ){\r
-    if( d_ground_eval[0]==( d_tgt ? p->d_true : p->d_false ) ){\r
-      d_child_counter = 0;\r
-    }\r
-  }else if( d_type==typ_bool_var ){\r
-    //get current value of the variable\r
-    TNode n = qi->getCurrentValue( d_n );\r
-    int vn = qi->getCurrentRepVar( qi->getVarNum( n ) );\r
-    if( vn==-1 ){\r
-      //evaluate the value, see if it is compatible\r
-      int e = p->evaluate( n );\r
-      if( ( e==1 && d_tgt ) || ( e==0 && !d_tgt ) ){\r
-        d_child_counter = 0;\r
-      }\r
-    }else{\r
-      //unassigned, set match to true/false\r
-      d_qni_bound[0] = vn;\r
-      qi->setMatch( p, vn, d_tgt ? p->d_true : p->d_false );\r
-      d_child_counter = 0;\r
-    }\r
-    if( d_child_counter==0 ){\r
-      d_qn.push_back( NULL );\r
-    }\r
-  }else if( d_type==typ_var ){\r
-    Assert( isHandledUfTerm( d_n ) );\r
-    Node f = getOperator( p, d_n );\r
-    Debug("qcf-match-debug") << "       reset: Var will match operators of " << f << std::endl;\r
-    TermArgTrie * qni = p->getTermDatabase()->getTermArgTrie( Node::null(), f );\r
-    if( qni!=NULL ){\r
-      d_qn.push_back( qni );\r
-    }\r
-    d_matched_basis = false;\r
-  }else if( d_type==typ_tsym || d_type==typ_tconstraint ){\r
-    for( std::map< int, int >::iterator it = d_qni_var_num.begin(); it != d_qni_var_num.end(); ++it ){\r
-      int repVar = qi->getCurrentRepVar( it->second );\r
-      if( qi->d_match[repVar].isNull() ){\r
-        Debug("qcf-match-debug") << "Force matching on child #" << it->first << ", which is var #" << repVar << std::endl;\r
-        d_qni_bound[it->first] = repVar;\r
-      }\r
-    }\r
-    d_qn.push_back( NULL );\r
-  }else if( d_type==typ_pred || d_type==typ_eq ){\r
-    //add initial constraint\r
-    Node nn[2];\r
-    int vn[2];\r
-    if( d_type==typ_pred ){\r
-      nn[0] = qi->getCurrentValue( d_n );\r
-      vn[0] = qi->getCurrentRepVar( qi->getVarNum( nn[0] ) );\r
-      nn[1] = p->getRepresentative( d_tgt ? p->d_true : p->d_false );\r
-      vn[1] = -1;\r
-      d_tgt = true;\r
-    }else{\r
-      for( unsigned i=0; i<2; i++ ){\r
-        TNode nc;\r
-        std::map< int, TNode >::iterator it = d_qni_gterm_rep.find( i );\r
-        if( it!=d_qni_gterm_rep.end() ){\r
-          nc = it->second;\r
-        }else{\r
-          nc = d_n[i];\r
-        }\r
-        nn[i] = qi->getCurrentValue( nc );\r
-        vn[i] = qi->getCurrentRepVar( qi->getVarNum( nn[i] ) );\r
-      }\r
-    }\r
-    bool success;\r
-    if( vn[0]==-1 && vn[1]==-1 ){\r
-      //Trace("qcf-explain") << "    reset : " << d_n << " check ground values " << nn[0] << " " << nn[1] << " (tgt=" << d_tgt << ")" << std::endl;\r
-      Debug("qcf-match-debug") << "       reset: check ground values " << nn[0] << " " << nn[1] << " (" << d_tgt << ")" << std::endl;\r
-      //just compare values\r
-      if( d_tgt ){\r
-        success = p->areMatchEqual( nn[0], nn[1] );\r
-      }else{\r
-        if( p->d_effort==QuantConflictFind::effort_conflict ){\r
-          success = p->areDisequal( nn[0], nn[1] );\r
-        }else{\r
-          success = p->areMatchDisequal( nn[0], nn[1] );\r
-        }\r
-      }\r
-    }else{\r
-      //otherwise, add a constraint to a variable\r
-      if( vn[1]!=-1 && vn[0]==-1 ){\r
-        //swap\r
-        Node t = nn[1];\r
-        nn[1] = nn[0];\r
-        nn[0] = t;\r
-        vn[0] = vn[1];\r
-        vn[1] = -1;\r
-      }\r
-      Debug("qcf-match-debug") << "       reset: add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << std::endl;\r
-      //add some constraint\r
-      int addc = qi->addConstraint( p, vn[0], nn[1], vn[1], d_tgt, false );\r
-      success = addc!=-1;\r
-      //if successful and non-redundant, store that we need to cleanup this\r
-      if( addc==1 ){\r
-        //Trace("qcf-explain") << "       reset: " << d_n << " add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << ", d_tgt = " << d_tgt << std::endl;\r
-        for( unsigned i=0; i<2; i++ ){\r
-          if( vn[i]!=-1 && std::find( d_qni_bound_except.begin(), d_qni_bound_except.end(), i )==d_qni_bound_except.end() ){\r
-            d_qni_bound[vn[i]] = vn[i];\r
-          }\r
-        }\r
-        d_qni_bound_cons[vn[0]] = nn[1];\r
-        d_qni_bound_cons_var[vn[0]] = vn[1];\r
-      }\r
-    }\r
-    //if successful, we will bind values to variables\r
-    if( success ){\r
-      d_qn.push_back( NULL );\r
-    }\r
-  }else{\r
-    if( d_children.empty() ){\r
-      //add dummy\r
-      d_qn.push_back( NULL );\r
-    }else{\r
-      if( d_tgt && d_n.getKind()==FORALL ){\r
-        //do nothing\r
-      }else{\r
-        //reset the first child to d_tgt\r
-        d_child_counter = 0;\r
-        getChild( d_child_counter )->reset( p, d_tgt, qi );\r
-      }\r
-    }\r
-  }\r
-  d_binding = false;\r
-  d_wasSet = true;\r
-  Debug("qcf-match") << "     reset: Finished reset for " << d_n << ", success = " << ( !d_qn.empty() || d_child_counter!=-1 ) << std::endl;\r
-}\r
-\r
-bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {\r
-  Debug("qcf-match") << "     Get next match for : " << d_n << ", type = ";\r
-  debugPrintType( "qcf-match", d_type );\r
-  Debug("qcf-match") << ", children = " << d_children.size() << ", binding = " << d_binding << std::endl;\r
-  if( d_type==typ_invalid || d_type==typ_ground ){\r
-    if( d_child_counter==0 ){\r
-      d_child_counter = -1;\r
-      return true;\r
-    }else{\r
-      d_wasSet = false;\r
-      return false;\r
-    }\r
-  }else if( d_type==typ_var || d_type==typ_eq || d_type==typ_pred || d_type==typ_bool_var || d_type==typ_tconstraint || d_type==typ_tsym ){\r
-    bool success = false;\r
-    bool terminate = false;\r
-    do {\r
-      bool doReset = false;\r
-      bool doFail = false;\r
-      if( !d_binding ){\r
-        if( doMatching( p, qi ) ){\r
-          Debug("qcf-match-debug") << "     - Matching succeeded" << std::endl;\r
-          d_binding = true;\r
-          d_binding_it = d_qni_bound.begin();\r
-          doReset = true;\r
-          //for tconstraint, add constraint\r
-          if( d_type==typ_tconstraint ){\r
-            std::map< Node, bool >::iterator it = qi->d_tconstraints.find( d_n );\r
-            if( it==qi->d_tconstraints.end() ){\r
-              qi->d_tconstraints[d_n] = d_tgt;\r
-              //store that we added this constraint\r
-              d_qni_bound_cons[0] = d_n;\r
-            }else if( d_tgt!=it->second ){\r
-              success = false;\r
-              terminate = true;\r
-            }\r
-          }\r
-        }else{\r
-          Debug("qcf-match-debug") << "     - Matching failed" << std::endl;\r
-          success = false;\r
-          terminate = true;\r
-        }\r
-      }else{\r
-        doFail = true;\r
-      }\r
-      if( d_binding ){\r
-        //also need to create match for each variable we bound\r
-        success = true;\r
-        Debug("qcf-match-debug") << "     Produce matches for bound variables by " << d_n << ", type = ";\r
-        debugPrintType( "qcf-match-debug", d_type );\r
-        Debug("qcf-match-debug") << "..." << std::endl;\r
-\r
-        while( ( success && d_binding_it!=d_qni_bound.end() ) || doFail ){\r
-          std::map< int, MatchGen * >::iterator itm;\r
-          if( !doFail ){\r
-            Debug("qcf-match-debug") << "       check variable " << d_binding_it->second << std::endl;\r
-            itm = qi->d_var_mg.find( d_binding_it->second );\r
-          }\r
-          if( doFail || ( d_binding_it->first!=0 && itm!=qi->d_var_mg.end() ) ){\r
-            Debug("qcf-match-debug") << "       we had bound variable " << d_binding_it->second << ", reset = " << doReset << std::endl;\r
-            if( doReset ){\r
-              itm->second->reset( p, true, qi );\r
-            }\r
-            if( doFail || !itm->second->getNextMatch( p, qi ) ){\r
-              do {\r
-                if( d_binding_it==d_qni_bound.begin() ){\r
-                  Debug("qcf-match-debug") << "       failed." << std::endl;\r
-                  success = false;\r
-                }else{\r
-                  --d_binding_it;\r
-                  Debug("qcf-match-debug") << "       decrement..." << std::endl;\r
-                }\r
-              }while( success && ( d_binding_it->first==0 || qi->d_var_mg.find( d_binding_it->second )==qi->d_var_mg.end() ) );\r
-              doReset = false;\r
-              doFail = false;\r
-            }else{\r
-              Debug("qcf-match-debug") << "       increment..." << std::endl;\r
-              ++d_binding_it;\r
-              doReset = true;\r
-            }\r
-          }else{\r
-            Debug("qcf-match-debug") << "       skip..." << d_binding_it->second << std::endl;\r
-            ++d_binding_it;\r
-            doReset = true;\r
-          }\r
-        }\r
-        if( !success ){\r
-          d_binding = false;\r
-        }else{\r
-          terminate = true;\r
-          if( d_binding_it==d_qni_bound.begin() ){\r
-            d_binding = false;\r
-          }\r
-        }\r
-      }\r
-    }while( !terminate );\r
-    //if not successful, clean up the variables you bound\r
-    if( !success ){\r
-      if( d_type==typ_eq || d_type==typ_pred ){\r
-        //clean up the constraints you added\r
-        for( std::map< int, TNode >::iterator it = d_qni_bound_cons.begin(); it != d_qni_bound_cons.end(); ++it ){\r
-          if( !it->second.isNull() ){\r
-            Debug("qcf-match") << "       Clean up bound var " << it->first << (d_tgt ? "!" : "") << " = " << it->second << std::endl;\r
-            std::map< int, int >::iterator itb = d_qni_bound_cons_var.find( it->first );\r
-            int vn = itb!=d_qni_bound_cons_var.end() ? itb->second : -1;\r
-            //Trace("qcf-explain") << "       cleanup: " << d_n << " remove constraint " << it->first << " -> " << it->second << " (vn=" << vn << ")" << ", d_tgt = " << d_tgt << std::endl;\r
-            qi->addConstraint( p, it->first, it->second, vn, d_tgt, true );\r
-          }\r
-        }\r
-        d_qni_bound_cons.clear();\r
-        d_qni_bound_cons_var.clear();\r
-        d_qni_bound.clear();\r
-      }else{\r
-        //clean up the matches you set\r
-        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){\r
-          Debug("qcf-match") << "       Clean up bound var " << it->second << std::endl;\r
-          Assert( it->second<qi->getNumVars() );\r
-          qi->d_match[ it->second ] = TNode::null();\r
-          qi->d_match_term[ it->second ] = TNode::null();\r
-        }\r
-        d_qni_bound.clear();\r
-      }\r
-      if( d_type==typ_tconstraint ){\r
-        //remove constraint if applicable\r
-        if( d_qni_bound_cons.find( 0 )!=d_qni_bound_cons.end() ){\r
-          qi->d_tconstraints.erase( d_n );\r
-          d_qni_bound_cons.clear();\r
-        }\r
-      }\r
-      /*\r
-      if( d_type==typ_var && p->d_effort==QuantConflictFind::effort_mc && !d_matched_basis ){\r
-        d_matched_basis = true;\r
-        Node f = getOperator( d_n );\r
-        TNode mbo = p->getTermDatabase()->getModelBasisOpTerm( f );\r
-        if( qi->setMatch( p, d_qni_var_num[0], mbo ) ){\r
-          success = true;\r
-          d_qni_bound[0] = d_qni_var_num[0];\r
-        }\r
-      }\r
-      */\r
-    }\r
-    Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;\r
-    d_wasSet = success;\r
-    return success;\r
-  }else if( d_type==typ_formula || d_type==typ_ite_var ){\r
-    bool success = false;\r
-    if( d_child_counter<0 ){\r
-      if( d_child_counter<-1 ){\r
-        success = true;\r
-        d_child_counter = -1;\r
-      }\r
-    }else{\r
-      while( !success && d_child_counter>=0 ){\r
-        //transition system based on d_child_counter\r
-        if( d_n.getKind()==OR || d_n.getKind()==AND ){\r
-          if( (d_n.getKind()==AND)==d_tgt ){\r
-            //all children must match simultaneously\r
-            if( getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
-              if( d_child_counter<(int)(getNumChildren()-1) ){\r
-                d_child_counter++;\r
-                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << std::endl;\r
-                getChild( d_child_counter )->reset( p, d_tgt, qi );\r
-              }else{\r
-                success = true;\r
-              }\r
-            }else{\r
-              //if( std::find( d_independent.begin(), d_independent.end(), d_child_counter )!=d_independent.end() ){\r
-              //  d_child_counter--;\r
-              //}else{\r
-              d_child_counter--;\r
-              //}\r
-            }\r
-          }else{\r
-            //one child must match\r
-            if( !getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
-              if( d_child_counter<(int)(getNumChildren()-1) ){\r
-                d_child_counter++;\r
-                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << ", one match" << std::endl;\r
-                getChild( d_child_counter )->reset( p, d_tgt, qi );\r
-              }else{\r
-                d_child_counter = -1;\r
-              }\r
-            }else{\r
-              success = true;\r
-            }\r
-          }\r
-        }else if( d_n.getKind()==IFF ){\r
-          //construct match based on both children\r
-          if( d_child_counter%2==0 ){\r
-            if( getChild( 0 )->getNextMatch( p, qi ) ){\r
-              d_child_counter++;\r
-              getChild( 1 )->reset( p, d_child_counter==1, qi );\r
-            }else{\r
-              if( d_child_counter==0 ){\r
-                d_child_counter = 2;\r
-                getChild( 0 )->reset( p, !d_tgt, qi );\r
-              }else{\r
-                d_child_counter = -1;\r
-              }\r
-            }\r
-          }\r
-          if( d_child_counter>=0 && d_child_counter%2==1 ){\r
-            if( getChild( 1 )->getNextMatch( p, qi ) ){\r
-              success = true;\r
-            }else{\r
-              d_child_counter--;\r
-            }\r
-          }\r
-        }else if( d_n.getKind()==ITE ){\r
-          if( d_child_counter%2==0 ){\r
-            int index1 = d_child_counter==4 ? 1 : 0;\r
-            if( getChild( index1 )->getNextMatch( p, qi ) ){\r
-              d_child_counter++;\r
-              getChild( d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2) )->reset( p, d_tgt, qi );\r
-            }else{\r
-              if( d_child_counter==4 || ( d_type==typ_ite_var && d_child_counter==2 ) ){\r
-                d_child_counter = -1;\r
-              }else{\r
-                d_child_counter +=2;\r
-                getChild( d_child_counter==2 ? 0 : 1 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );\r
-              }\r
-            }\r
-          }\r
-          if( d_child_counter>=0 && d_child_counter%2==1 ){\r
-            int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2);\r
-            if( getChild( index2 )->getNextMatch( p, qi ) ){\r
-              success = true;\r
-            }else{\r
-              d_child_counter--;\r
-            }\r
-          }\r
-        }else if( d_n.getKind()==FORALL ){\r
-          if( getChild( d_child_counter )->getNextMatch( p, qi ) ){\r
-            success = true;\r
-          }else{\r
-            d_child_counter = -1;\r
-          }\r
-        }\r
-      }\r
-        d_wasSet = success;\r
-      Debug("qcf-match") << "    ...finished construct match for " << d_n << ", success = " << success << std::endl;\r
-      return success;\r
-    }\r
-  }\r
-  Debug("qcf-match") << "    ...already finished for " << d_n << std::endl;\r
-  return false;\r
-}\r
-\r
-bool MatchGen::getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp ) {\r
-  if( d_type==typ_eq ){\r
-    Node n[2];\r
-    for( unsigned i=0; i<2; i++ ){\r
-      Trace("qcf-explain") << "Explain term " << d_n[i] << "..." << std::endl;\r
-      n[i] = getExplanationTerm( p, qi, d_n[i], exp );\r
-    }\r
-    Node eq = n[0].eqNode( n[1] );\r
-    if( !d_tgt_orig ){\r
-      eq = eq.negate();\r
-    }\r
-    exp.push_back( eq );\r
-    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << eq << ", set = " << d_wasSet << std::endl;\r
-    return true;\r
-  }else if( d_type==typ_pred ){\r
-    Trace("qcf-explain") << "Explain term " << d_n << "..." << std::endl;\r
-    Node n = getExplanationTerm( p, qi, d_n, exp );\r
-    if( !d_tgt_orig ){\r
-      n = n.negate();\r
-    }\r
-    exp.push_back( n );\r
-    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << n << ", set = " << d_wasSet << std::endl;\r
-    return true;\r
-  }else if( d_type==typ_formula ){\r
-    Trace("qcf-explain") << "Explanation get for " << d_n << ", counter = " << d_child_counter << ", tgt = " << d_tgt_orig << ", set = " << d_wasSet << std::endl;\r
-    if( d_n.getKind()==OR || d_n.getKind()==AND ){\r
-      if( (d_n.getKind()==AND)==d_tgt ){\r
-        for( unsigned i=0; i<getNumChildren(); i++ ){\r
-          if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
-            return false;\r
-          }\r
-        }\r
-      }else{\r
-        return getChild( d_child_counter )->getExplanation( p, qi, exp );\r
-      }\r
-    }else if( d_n.getKind()==IFF ){\r
-      for( unsigned i=0; i<2; i++ ){\r
-        if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
-          return false;\r
-        }\r
-      }\r
-    }else if( d_n.getKind()==ITE ){\r
-      for( unsigned i=0; i<3; i++ ){\r
-        bool isActive = ( ( i==0 && d_child_counter!=5 ) ||\r
-                          ( i==1 && d_child_counter!=( d_tgt ? 3 : 1 ) ) ||\r
-                          ( i==2 && d_child_counter!=( d_tgt ? 1 : 3 ) ) );\r
-        if( isActive ){\r
-          if( !getChild( i )->getExplanation( p, qi, exp ) ){\r
-            return false;\r
-          }\r
-        }\r
-      }\r
-    }else{\r
-      return false;\r
-    }\r
-    return true;\r
-  }else{\r
-    return false;\r
-  }\r
-}\r
-\r
-Node MatchGen::getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp ) {\r
-  Node v = qi->getCurrentExpValue( t );\r
-  if( isHandledUfTerm( t ) ){\r
-    for( unsigned i=0; i<t.getNumChildren(); i++ ){\r
-      Node vi = getExplanationTerm( p, qi, t[i], exp );\r
-      if( vi!=v[i] ){\r
-        Node eq = vi.eqNode( v[i] );\r
-        if( std::find( exp.begin(), exp.end(), eq )==exp.end() ){\r
-          Trace("qcf-explain") << "  add : " << eq << "." << std::endl;\r
-          exp.push_back( eq );\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return v;\r
-}\r
-\r
-bool MatchGen::doMatching( QuantConflictFind * p, QuantInfo * qi ) {\r
-  if( !d_qn.empty() ){\r
-    if( d_qn[0]==NULL ){\r
-      d_qn.clear();\r
-      return true;\r
-    }else{\r
-      Assert( d_type==typ_var );\r
-      Assert( d_qni_size>0 );\r
-      bool invalidMatch;\r
-      do {\r
-        invalidMatch = false;\r
-        Debug("qcf-match-debug") << "       Do matching " << d_n << " " << d_qn.size() << " " << d_qni.size() << std::endl;\r
-        if( d_qn.size()==d_qni.size()+1 ) {\r
-          int index = (int)d_qni.size();\r
-          //initialize\r
-          TNode val;\r
-          std::map< int, int >::iterator itv = d_qni_var_num.find( index );\r
-          if( itv!=d_qni_var_num.end() ){\r
-            //get the representative variable this variable is equal to\r
-            int repVar = qi->getCurrentRepVar( itv->second );\r
-            Debug("qcf-match-debug") << "       Match " << index << " is a variable " << itv->second << ", which is repVar " << repVar << std::endl;\r
-            //get the value the rep variable\r
-            //std::map< int, TNode >::iterator itm = qi->d_match.find( repVar );\r
-            if( !qi->d_match[repVar].isNull() ){\r
-              val = qi->d_match[repVar];\r
-              Debug("qcf-match-debug") << "       Variable is already bound to " << val << std::endl;\r
-            }else{\r
-              //binding a variable\r
-              d_qni_bound[index] = repVar;\r
-              std::map< TNode, TermArgTrie >::iterator it = d_qn[index]->d_data.begin();\r
-              if( it != d_qn[index]->d_data.end() ) {\r
-                d_qni.push_back( it );\r
-                //set the match\r
-                if( it->first.getType().isSubtypeOf( qi->d_var_types[repVar] ) && qi->setMatch( p, d_qni_bound[index], it->first ) ){\r
-                  Debug("qcf-match-debug") << "       Binding variable" << std::endl;\r
-                  if( d_qn.size()<d_qni_size ){\r
-                    d_qn.push_back( &it->second );\r
-                  }\r
-                }else{\r
-                  Debug("qcf-match") << "       Binding variable, currently fail." << std::endl;\r
-                  invalidMatch = true;\r
-                }\r
-              }else{\r
-                Debug("qcf-match-debug") << "       Binding variable, fail, no more variables to bind" << std::endl;\r
-                d_qn.pop_back();\r
-              }\r
-            }\r
-          }else{\r
-            Debug("qcf-match-debug") << "       Match " << index << " is ground term" << std::endl;\r
-            Assert( d_qni_gterm.find( index )!=d_qni_gterm.end() );\r
-            Assert( d_qni_gterm_rep.find( index )!=d_qni_gterm_rep.end() );\r
-            val = d_qni_gterm_rep[index];\r
-            Assert( !val.isNull() );\r
-          }\r
-          if( !val.isNull() ){\r
-            //constrained by val\r
-            std::map< TNode, TermArgTrie >::iterator it = d_qn[index]->d_data.find( val );\r
-            if( it!=d_qn[index]->d_data.end() ){\r
-              Debug("qcf-match-debug") << "       Match" << std::endl;\r
-              d_qni.push_back( it );\r
-              if( d_qn.size()<d_qni_size ){\r
-                d_qn.push_back( &it->second );\r
-              }\r
-            }else{\r
-              Debug("qcf-match-debug") << "       Failed to match" << std::endl;\r
-              d_qn.pop_back();\r
-            }\r
-          }\r
-        }else{\r
-          Assert( d_qn.size()==d_qni.size() );\r
-          int index = d_qni.size()-1;\r
-          //increment if binding this variable\r
-          bool success = false;\r
-          std::map< int, int >::iterator itb = d_qni_bound.find( index );\r
-          if( itb!=d_qni_bound.end() ){\r
-            d_qni[index]++;\r
-            if( d_qni[index]!=d_qn[index]->d_data.end() ){\r
-              success = true;\r
-              if( qi->setMatch( p, itb->second, d_qni[index]->first ) ){\r
-                Debug("qcf-match-debug") << "       Bind next variable" << std::endl;\r
-                if( d_qn.size()<d_qni_size ){\r
-                  d_qn.push_back( &d_qni[index]->second );\r
-                }\r
-              }else{\r
-                Debug("qcf-match-debug") << "       Bind next variable, currently fail" << std::endl;\r
-                invalidMatch = true;\r
-              }\r
-            }else{\r
-              qi->d_match[ itb->second ] = TNode::null();\r
-              qi->d_match_term[ itb->second ] = TNode::null();\r
-              Debug("qcf-match-debug") << "       Bind next variable, no more variables to bind" << std::endl;\r
-            }\r
-          }else{\r
-            //TODO : if it equal to something else, also try that\r
-          }\r
-          //if not incrementing, move to next\r
-          if( !success ){\r
-            d_qn.pop_back();\r
-            d_qni.pop_back();\r
-          }\r
-        }\r
-      }while( ( !d_qn.empty() && d_qni.size()!=d_qni_size ) || invalidMatch );\r
-      if( d_qni.size()==d_qni_size ){\r
-        //Assert( !d_qni[d_qni.size()-1]->second.d_data.empty() );\r
-        //Debug("qcf-match-debug") << "       We matched " << d_qni[d_qni.size()-1]->second.d_children.begin()->first << std::endl;\r
-        Assert( !d_qni[d_qni.size()-1]->second.d_data.empty() );\r
-        TNode t = d_qni[d_qni.size()-1]->second.d_data.begin()->first;\r
-        Debug("qcf-match-debug") << "       " << d_n << " matched " << t << std::endl;\r
-        qi->d_match_term[d_qni_var_num[0]] = t;\r
-        //set the match terms\r
-        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){\r
-          Debug("qcf-match-debug") << "       position " << it->first << " bounded " << it->second << " / " << qi->d_q[0].getNumChildren() << std::endl;\r
-          //if( it->second<(int)qi->d_q[0].getNumChildren() ){   //if it is an actual variable, we are interested in knowing the actual term\r
-          if( it->first>0 ){\r
-            Assert( !qi->d_match[ it->second ].isNull() );\r
-            Assert( p->areEqual( t[it->first-1], qi->d_match[ it->second ] ) );\r
-            qi->d_match_term[it->second] = t[it->first-1];\r
-          }\r
-          //}\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return !d_qn.empty();\r
-}\r
-\r
-void MatchGen::debugPrintType( const char * c, short typ, bool isTrace ) {\r
-  if( isTrace ){\r
-    switch( typ ){\r
-    case typ_invalid: Trace(c) << "invalid";break;\r
-    case typ_ground: Trace(c) << "ground";break;\r
-    case typ_eq: Trace(c) << "eq";break;\r
-    case typ_pred: Trace(c) << "pred";break;\r
-    case typ_formula: Trace(c) << "formula";break;\r
-    case typ_var: Trace(c) << "var";break;\r
-    case typ_ite_var: Trace(c) << "ite_var";break;\r
-    case typ_bool_var: Trace(c) << "bool_var";break;\r
-    }\r
-  }else{\r
-    switch( typ ){\r
-    case typ_invalid: Debug(c) << "invalid";break;\r
-    case typ_ground: Debug(c) << "ground";break;\r
-    case typ_eq: Debug(c) << "eq";break;\r
-    case typ_pred: Debug(c) << "pred";break;\r
-    case typ_formula: Debug(c) << "formula";break;\r
-    case typ_var: Debug(c) << "var";break;\r
-    case typ_ite_var: Debug(c) << "ite_var";break;\r
-    case typ_bool_var: Debug(c) << "bool_var";break;\r
-    }\r
-  }\r
-}\r
-\r
-void MatchGen::setInvalid() {\r
-  d_type = typ_invalid;\r
-  d_children.clear();\r
-}\r
-\r
-bool MatchGen::isHandledBoolConnective( TNode n ) {\r
-  return n.getType().isBoolean() && ( n.getKind()==OR || n.getKind()==AND || n.getKind()==IFF || n.getKind()==ITE || n.getKind()==FORALL || n.getKind()==NOT );\r
-}\r
-\r
-bool MatchGen::isHandledUfTerm( TNode n ) {\r
-  //return n.getKind()==APPLY_UF || n.getKind()==STORE || n.getKind()==SELECT ||\r
-  //       n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR_TOTAL || n.getKind()==APPLY_TESTER;\r
-  return inst::Trigger::isAtomicTriggerKind( n.getKind() );\r
-}\r
-\r
-Node MatchGen::getOperator( QuantConflictFind * p, Node n ) {\r
-  if( isHandledUfTerm( n ) ){\r
-    return p->getTermDatabase()->getOperator( n );\r
-  }else{\r
-    return Node::null();\r
-  }\r
-}\r
-\r
-bool MatchGen::isHandled( TNode n ) {\r
-  if( n.getKind()!=BOUND_VARIABLE && n.hasBoundVar() ){\r
-    if( !isHandledBoolConnective( n ) && !isHandledUfTerm( n ) && n.getKind()!=EQUAL && n.getKind()!=ITE ){\r
-      return false;\r
-    }\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      if( !isHandled( n[i] ) ){\r
-        return false;\r
-      }\r
-    }\r
-  }\r
-  return true;\r
-}\r
-\r
-\r
-QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :\r
-QuantifiersModule( qe ),\r
-d_conflict( c, false ),\r
-d_qassert( c ) {\r
-  d_fid_count = 0;\r
-  d_true = NodeManager::currentNM()->mkConst<bool>(true);\r
-  d_false = NodeManager::currentNM()->mkConst<bool>(false);\r
-}\r
-\r
-Node QuantConflictFind::mkEqNode( Node a, Node b ) {\r
-  if( a.getType().isBoolean() ){\r
-    return a.iffNode( b );\r
-  }else{\r
-    return a.eqNode( b );\r
-  }\r
-}\r
-\r
-//-------------------------------------------------- registration\r
-\r
-void QuantConflictFind::registerQuantifier( Node q ) {\r
-  if( d_quantEngine->hasOwnership( q, this ) ){\r
-    d_quants.push_back( q );\r
-    d_quant_id[q] = d_quants.size();\r
-    Trace("qcf-qregister") << "Register ";\r
-    debugPrintQuant( "qcf-qregister", q );\r
-    Trace("qcf-qregister") << " : " << q << std::endl;\r
-    //make QcfNode structure\r
-    Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;\r
-    d_qinfo[q].initialize( q, q[1] );\r
-\r
-    //debug print\r
-    Trace("qcf-qregister") << "- Flattened structure is :" << std::endl;\r
-    Trace("qcf-qregister") << "    ";\r
-    debugPrintQuantBody( "qcf-qregister", q, q[1] );\r
-    Trace("qcf-qregister") << std::endl;\r
-    if( d_qinfo[q].d_vars.size()>q[0].getNumChildren() ){\r
-      Trace("qcf-qregister") << "  with additional constraints : " << std::endl;\r
-      for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){\r
-        Trace("qcf-qregister") << "    ?x" << j << " = ";\r
-        debugPrintQuantBody( "qcf-qregister", q, d_qinfo[q].d_vars[j], false );\r
-        Trace("qcf-qregister") << std::endl;\r
-      }\r
-    }\r
-\r
-    Trace("qcf-qregister") << "Done registering quantifier." << std::endl;\r
-  }\r
-}\r
-\r
-int QuantConflictFind::evaluate( Node n, bool pref, bool hasPref ) {\r
-  int ret = 0;\r
-  if( n.getKind()==EQUAL ){\r
-    Node n1 = evaluateTerm( n[0] );\r
-    Node n2 = evaluateTerm( n[1] );\r
-    Debug("qcf-eval") << "Evaluate : Normalize " << n << " to " << n1 << " = " << n2 << std::endl;\r
-    if( areEqual( n1, n2 ) ){\r
-      ret = 1;\r
-    }else if( areDisequal( n1, n2 ) ){\r
-      ret = -1;\r
-    }\r
-    //else if( d_effort>QuantConflictFind::effort_conflict ){\r
-    //  ret = -1;\r
-    //}\r
-  }else if( MatchGen::isHandledUfTerm( n ) ){  //predicate\r
-    Node nn = evaluateTerm( n );\r
-    Debug("qcf-eval") << "Evaluate : Normalize " << nn << " to " << n << std::endl;\r
-    if( areEqual( nn, d_true ) ){\r
-      ret = 1;\r
-    }else if( areEqual( nn, d_false ) ){\r
-      ret = -1;\r
-    }\r
-    //else if( d_effort>QuantConflictFind::effort_conflict ){\r
-    //  ret = -1;\r
-    //}\r
-  }else if( n.getKind()==NOT ){\r
-    return -evaluate( n[0] );\r
-  }else if( n.getKind()==ITE ){\r
-    int cev1 = evaluate( n[0] );\r
-    int cevc[2] = { 0, 0 };\r
-    for( unsigned i=0; i<2; i++ ){\r
-      if( ( i==0 && cev1!=-1 ) || ( i==1 && cev1!=1 ) ){\r
-        cevc[i] = evaluate( n[i+1] );\r
-        if( cev1!=0 ){\r
-          ret = cevc[i];\r
-          break;\r
-        }else if( cevc[i]==0 ){\r
-          break;\r
-        }\r
-      }\r
-    }\r
-    if( ret==0 && cevc[0]!=0 && cevc[0]==cevc[1] ){\r
-      ret = cevc[0];\r
-    }\r
-  }else if( n.getKind()==IFF ){\r
-    int cev1 = evaluate( n[0] );\r
-    if( cev1!=0 ){\r
-      int cev2 = evaluate( n[1] );\r
-      if( cev2!=0 ){\r
-        ret = cev1==cev2 ? 1 : -1;\r
-      }\r
-    }\r
-\r
-  }else{\r
-    int ssval = 0;\r
-    if( n.getKind()==OR ){\r
-      ssval = 1;\r
-    }else if( n.getKind()==AND ){\r
-      ssval = -1;\r
-    }\r
-    bool isUnk = false;\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      int cev = evaluate( n[i] );\r
-      if( cev==ssval ){\r
-        ret = ssval;\r
-        break;\r
-      }else if( cev==0 ){\r
-        isUnk = true;\r
-      }\r
-    }\r
-    if( ret==0 && !isUnk ){\r
-      ret = -ssval;\r
-    }\r
-  }\r
-  Debug("qcf-eval") << "Evaluate " << n << " to " << ret << std::endl;\r
-  return ret;\r
-}\r
-\r
-short QuantConflictFind::getMaxQcfEffort() {\r
-  if( options::qcfMode()==QCF_CONFLICT_ONLY ){\r
-    return effort_conflict;\r
-  }else if( options::qcfMode()==QCF_PROP_EQ ){\r
-    return effort_prop_eq;\r
-  }else if( options::qcfMode()==QCF_MC ){\r
-    return effort_mc;\r
-  }else{\r
-    return 0;\r
-  }\r
-}\r
-\r
-bool QuantConflictFind::areMatchEqual( TNode n1, TNode n2 ) {\r
-  //if( d_effort==QuantConflictFind::effort_mc ){\r
-  //  return n1==n2 || !areDisequal( n1, n2 );\r
-  //}else{\r
-  return n1==n2;\r
-  //}\r
-}\r
-\r
-bool QuantConflictFind::areMatchDisequal( TNode n1, TNode n2 ) {\r
-  //if( d_effort==QuantConflictFind::effort_conflict ){\r
-  //  return areDisequal( n1, n2 );\r
-  //}else{\r
-  return n1!=n2;\r
-  //}\r
-}\r
-\r
-//-------------------------------------------------- handling assertions / eqc\r
-\r
-void QuantConflictFind::assertNode( Node q ) {\r
-  if( d_quantEngine->hasOwnership( q, this ) ){\r
-    Trace("qcf-proc") << "QCF : assertQuantifier : ";\r
-    debugPrintQuant("qcf-proc", q);\r
-    Trace("qcf-proc") << std::endl;\r
-    d_qassert.push_back( q );\r
-    //set the eqRegistries that this depends on to true\r
-    //for( std::map< EqRegistry *, bool >::iterator it = d_qinfo[q].d_rel_eqr.begin(); it != d_qinfo[q].d_rel_eqr.end(); ++it ){\r
-    //  it->first->d_active.set( true );\r
-    //}\r
-  }\r
-}\r
-\r
-Node QuantConflictFind::evaluateTerm( Node n ) {\r
-  if( MatchGen::isHandledUfTerm( n ) ){\r
-    Node f = MatchGen::getOperator( this, n );\r
-    Node nn;\r
-    if( getEqualityEngine()->hasTerm( n ) ){\r
-      nn = getTermDatabase()->existsTerm( f, n );\r
-    }else{\r
-      std::vector< TNode > args;\r
-      for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-        Node c = evaluateTerm( n[i] );\r
-        args.push_back( c );\r
-      }\r
-      nn = getTermDatabase()->d_func_map_trie[f].existsTerm( args );\r
-    }\r
-    if( !nn.isNull() ){\r
-      Debug("qcf-eval") << "GT: Term " << nn << " for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;\r
-      return getRepresentative( nn );\r
-    }else{\r
-      Debug("qcf-eval") << "GT: No term for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;\r
-      return n;\r
-    }\r
-  }else if( n.getKind()==ITE ){\r
-    int v = evaluate( n[0], false, false );\r
-    if( v==1 ){\r
-      return evaluateTerm( n[1] );\r
-    }else if( v==-1 ){\r
-      return evaluateTerm( n[2] );\r
-    }\r
-  }\r
-  return getRepresentative( n );\r
-}\r
-\r
-/** new node */\r
-void QuantConflictFind::newEqClass( Node n ) {\r
-\r
-}\r
-\r
-/** merge */\r
-void QuantConflictFind::merge( Node a, Node b ) {\r
-\r
-}\r
-\r
-/** assert disequal */\r
-void QuantConflictFind::assertDisequal( Node a, Node b ) {\r
-\r
-}\r
-\r
-//-------------------------------------------------- check function\r
-\r
-bool QuantConflictFind::needsCheck( Theory::Effort level ) {\r
-  bool performCheck = false;\r
-  if( options::quantConflictFind() && !d_conflict ){\r
-    if( level==Theory::EFFORT_LAST_CALL ){\r
-      performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_LAST_CALL;\r
-    }else if( level==Theory::EFFORT_FULL ){\r
-      performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_DEFAULT;\r
-    }else if( level==Theory::EFFORT_STANDARD ){\r
-      performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_STD;\r
-    }\r
-  }\r
-  return performCheck;\r
-}\r
-\r
-void QuantConflictFind::reset_round( Theory::Effort level ) {\r
-  d_needs_computeRelEqr = true;\r
-}\r
-\r
-/** check */\r
-void QuantConflictFind::check( Theory::Effort level, unsigned quant_e ) {\r
-  if( quant_e==QuantifiersEngine::QEFFORT_CONFLICT ){\r
-    Trace("qcf-check") << "QCF : check : " << level << std::endl;\r
-    if( d_conflict ){\r
-      Trace("qcf-check2") << "QCF : finished check : already in conflict." << std::endl;\r
-      if( level>=Theory::EFFORT_FULL ){\r
-        Trace("qcf-warn") << "ALREADY IN CONFLICT? " << level << std::endl;\r
-        //Assert( false );\r
-      }\r
-    }else{\r
-      int addedLemmas = 0;\r
-      ++(d_statistics.d_inst_rounds);\r
-      double clSet = 0;\r
-      int prevEt = 0;\r
-      if( Trace.isOn("qcf-engine") ){\r
-        prevEt = d_statistics.d_entailment_checks.getData();\r
-        clSet = double(clock())/double(CLOCKS_PER_SEC);\r
-        Trace("qcf-engine") << "---Conflict Find Engine Round, effort = " << level << "---" << std::endl;\r
-      }\r
-      computeRelevantEqr();\r
-\r
-      //determine order for quantified formulas\r
-      std::vector< Node > qorder;\r
-      std::map< Node, bool > qassert;\r
-      //mark which are asserted\r
-      for( unsigned i=0; i<d_qassert.size(); i++ ){\r
-        qassert[d_qassert[i]] = true;\r
-      }\r
-      //add which ones are specified in the order\r
-      for( unsigned i=0; i<d_quant_order.size(); i++ ){\r
-        Node n = d_quant_order[i];\r
-        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() && qassert.find( n )!=qassert.end() ){\r
-          qorder.push_back( n );\r
-        }\r
-      }\r
-      d_quant_order.clear();\r
-      d_quant_order.insert( d_quant_order.begin(), qorder.begin(), qorder.end() );\r
-      //add remaining\r
-      for( unsigned i=0; i<d_qassert.size(); i++ ){\r
-        Node n = d_qassert[i];\r
-        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() ){\r
-          qorder.push_back( n );\r
-        }\r
-      }\r
-\r
-      if( Trace.isOn("qcf-debug") ){\r
-        Trace("qcf-debug") << std::endl;\r
-        debugPrint("qcf-debug");\r
-        Trace("qcf-debug") << std::endl;\r
-      }\r
-      short end_e = getMaxQcfEffort();\r
-      for( short e = effort_conflict; e<=end_e; e++ ){\r
-        d_effort = e;\r
-        Trace("qcf-check") << "Checking quantified formulas at effort " << e << "..." << std::endl;\r
-        for( unsigned j=0; j<qorder.size(); j++ ){\r
-          Node q = qorder[j];\r
-          QuantInfo * qi = &d_qinfo[q];\r
-\r
-          Assert( d_qinfo.find( q )!=d_qinfo.end() );\r
-          if( qi->d_mg->isValid() ){\r
-            Trace("qcf-check") << "Check quantified formula ";\r
-            debugPrintQuant("qcf-check", q);\r
-            Trace("qcf-check") << " : " << q << "..." << std::endl;\r
-\r
-            Trace("qcf-check-debug") << "Reset round..." << std::endl;\r
-            qi->reset_round( this );\r
-            //try to make a matches making the body false\r
-            Trace("qcf-check-debug") << "Get next match..." << std::endl;\r
-            while( qi->d_mg->getNextMatch( this, qi ) ){\r
-              Trace("qcf-inst") << "*** Produced match at effort " << e << " : " << std::endl;\r
-              qi->debugPrintMatch("qcf-inst");\r
-              Trace("qcf-inst") << std::endl;\r
-              std::vector< int > assigned;\r
-              if( !qi->isMatchSpurious( this ) ){\r
-                if( qi->completeMatch( this, assigned ) ){\r
-                  std::vector< Node > terms;\r
-                  qi->getMatch( terms );\r
-                  if( !qi->isTConstraintSpurious( this, terms ) ){\r
-                    if( Debug.isOn("qcf-check-inst") ){\r
-                      //if( e==effort_conflict ){\r
-                      Node inst = d_quantEngine->getInstantiation( q, terms );\r
-                      Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;\r
-                      Assert( evaluate( inst )!=1 );\r
-                      Assert( evaluate( inst )==-1 || e>effort_conflict );\r
-                      //}\r
-                    }\r
-                    if( d_quantEngine->addInstantiation( q, terms, false ) ){\r
-                      Trace("qcf-check") << "   ... Added instantiation" << std::endl;\r
-                      Trace("qcf-inst") << "*** Was from effort " << e << " : " << std::endl;\r
-                      qi->debugPrintMatch("qcf-inst");\r
-                      Trace("qcf-inst") << std::endl;\r
-                      ++addedLemmas;\r
-                      if( e==effort_conflict ){\r
-                        d_quant_order.insert( d_quant_order.begin(), q );\r
-                        d_conflict.set( true );\r
-                        ++(d_statistics.d_conflict_inst);\r
-                        break;\r
-                      }else if( e==effort_prop_eq ){\r
-                        ++(d_statistics.d_prop_inst);\r
-                      }\r
-                    }else{\r
-                      Trace("qcf-inst") << "   ... Failed to add instantiation" << std::endl;\r
-                      //Assert( false );\r
-                    }\r
-                  }\r
-                  //clean up assigned\r
-                  qi->revertMatch( assigned );\r
-                  d_tempCache.clear();\r
-                }else{\r
-                  Trace("qcf-inst") << "   ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;\r
-                }\r
-              }else{\r
-                Trace("qcf-inst") << "   ... Spurious instantiation (match is inconsistent)" << std::endl;\r
-              }\r
-            }\r
-            if( d_conflict ){\r
-              break;\r
-            }\r
-          }\r
-        }\r
-        if( addedLemmas>0 ){\r
-          break;\r
-        }\r
-      }\r
-      if( Trace.isOn("qcf-engine") ){\r
-        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);\r
-        Trace("qcf-engine") << "Finished conflict find engine, time = " << (clSet2-clSet);\r
-        if( addedLemmas>0 ){\r
-          Trace("qcf-engine") << ", effort = " << ( d_effort==effort_conflict ? "conflict" : ( d_effort==effort_prop_eq ? "prop_eq" : "mc" ) );\r
-          Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;\r
-        }\r
-        Trace("qcf-engine") << std::endl;\r
-        int currEt = d_statistics.d_entailment_checks.getData();\r
-        if( currEt!=prevEt ){\r
-          Trace("qcf-engine") << "  Entailment checks = " << ( currEt - prevEt ) << std::endl;\r
-        }\r
-      }\r
-      Trace("qcf-check2") << "QCF : finished check : " << level << std::endl;\r
-    }\r
-  }\r
-}\r
-\r
-void QuantConflictFind::computeRelevantEqr() {\r
-  if( d_needs_computeRelEqr ){\r
-    d_needs_computeRelEqr = false;\r
-    Trace("qcf-check") << "Compute relevant equalities..." << std::endl;\r
-    //d_uf_terms.clear();\r
-    //d_eqc_uf_terms.clear();\r
-    d_eqcs.clear();\r
-    d_model_basis.clear();\r
-    //d_arg_reps.clear();\r
-    //double clSet = 0;\r
-    //if( Trace.isOn("qcf-opt") ){\r
-    //  clSet = double(clock())/double(CLOCKS_PER_SEC);\r
-    //}\r
-\r
-    //long nTermst = 0;\r
-    //long nTerms = 0;\r
-    //long nEqc = 0;\r
-\r
-    //which nodes are irrelevant for disequality matches\r
-    std::map< TNode, bool > irrelevant_dnode;\r
-    //now, store matches\r
-    eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );\r
-    while( !eqcs_i.isFinished() ){\r
-      //nEqc++;\r
-      Node r = (*eqcs_i);\r
-      if( getTermDatabase()->hasTermCurrent( r ) ){\r
-        TypeNode rtn = r.getType();\r
-        if( options::qcfMode()==QCF_MC ){\r
-          std::map< TypeNode, std::vector< TNode > >::iterator itt = d_eqcs.find( rtn );\r
-          if( itt==d_eqcs.end() ){\r
-            Node mb = getTermDatabase()->getModelBasisTerm( rtn );\r
-            if( !getEqualityEngine()->hasTerm( mb ) ){\r
-              Trace("qcf-warn") << "WARNING: Model basis term does not exist!" << std::endl;\r
-              Assert( false );\r
-            }\r
-            Node mbr = getRepresentative( mb );\r
-            if( mbr!=r ){\r
-              d_eqcs[rtn].push_back( mbr );\r
-            }\r
-            d_eqcs[rtn].push_back( r );\r
-            d_model_basis[rtn] = mb;\r
-          }else{\r
-            itt->second.push_back( r );\r
-          }\r
-        }else{\r
-          d_eqcs[rtn].push_back( r );\r
-        }\r
-      }\r
-      ++eqcs_i;\r
-    }\r
-    /*\r
-    if( Trace.isOn("qcf-opt") ){\r
-      double clSet2 = double(clock())/double(CLOCKS_PER_SEC);\r
-      Trace("qcf-opt") << "Compute rel eqc : " << std::endl;\r
-      Trace("qcf-opt") << "   " << nEqc << " equivalence classes. " << std::endl;\r
-      Trace("qcf-opt") << "   " << nTerms << " / " << nTermst << " terms." << std::endl;\r
-      Trace("qcf-opt") << "   Time : " << (clSet2-clSet) << std::endl;\r
-    }\r
-    */\r
-  }\r
-}\r
-\r
-\r
-//-------------------------------------------------- debugging\r
-\r
-\r
-void QuantConflictFind::debugPrint( const char * c ) {\r
-  //print the equivalance classes\r
-  Trace(c) << "----------EQ classes" << std::endl;\r
-  eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );\r
-  while( !eqcs_i.isFinished() ){\r
-    Node n = (*eqcs_i);\r
-    //if( !n.getType().isInteger() ){\r
-    Trace(c) << "  - " << n << " : {";\r
-    eq::EqClassIterator eqc_i = eq::EqClassIterator( n, getEqualityEngine() );\r
-    bool pr = false;\r
-    while( !eqc_i.isFinished() ){\r
-      Node nn = (*eqc_i);\r
-      if( nn.getKind()!=EQUAL && nn!=n ){\r
-        Trace(c) << (pr ? "," : "" ) << " " << nn;\r
-        pr = true;\r
-      }\r
-      ++eqc_i;\r
-    }\r
-    Trace(c) << (pr ? " " : "" ) << "}" << std::endl;\r
-    /*\r
-    EqcInfo * eqcn = getEqcInfo( n, false );\r
-    if( eqcn ){\r
-      Trace(c) << "    DEQ : {";\r
-      pr = false;\r
-      for( NodeBoolMap::iterator it = eqcn->d_diseq.begin(); it != eqcn->d_diseq.end(); ++it ){\r
-        if( (*it).second ){\r
-          Trace(c) << (pr ? "," : "" ) << " " << (*it).first;\r
-          pr = true;\r
-        }\r
-      }\r
-      Trace(c) << (pr ? " " : "" ) << "}" << std::endl;\r
-    }\r
-    //}\r
-    */\r
-    ++eqcs_i;\r
-  }\r
-}\r
-\r
-void QuantConflictFind::debugPrintQuant( const char * c, Node q ) {\r
-  Trace(c) << "Q" << d_quant_id[q];\r
-}\r
-\r
-void QuantConflictFind::debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum ) {\r
-  if( n.getNumChildren()==0 ){\r
-    Trace(c) << n;\r
-  }else if( doVarNum && d_qinfo[q].d_var_num.find( n )!=d_qinfo[q].d_var_num.end() ){\r
-    Trace(c) << "?x" << d_qinfo[q].d_var_num[n];\r
-  }else{\r
-    Trace(c) << "(";\r
-    if( n.getKind()==APPLY_UF ){\r
-      Trace(c) << n.getOperator();\r
-    }else{\r
-      Trace(c) << n.getKind();\r
-    }\r
-    for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
-      Trace(c) << " ";\r
-      debugPrintQuantBody( c, q, n[i] );\r
-    }\r
-    Trace(c) << ")";\r
-  }\r
-}\r
-\r
-QuantConflictFind::Statistics::Statistics():\r
-  d_inst_rounds("QuantConflictFind::Inst_Rounds", 0),\r
-  d_conflict_inst("QuantConflictFind::Instantiations_Conflict_Find", 0 ),\r
-  d_prop_inst("QuantConflictFind::Instantiations_Prop", 0 ),\r
-  d_entailment_checks("QuantConflictFind::Entailment_Checks",0)\r
-{\r
-  StatisticsRegistry::registerStat(&d_inst_rounds);\r
-  StatisticsRegistry::registerStat(&d_conflict_inst);\r
-  StatisticsRegistry::registerStat(&d_prop_inst);\r
-  StatisticsRegistry::registerStat(&d_entailment_checks);\r
-}\r
-\r
-QuantConflictFind::Statistics::~Statistics(){\r
-  StatisticsRegistry::unregisterStat(&d_inst_rounds);\r
-  StatisticsRegistry::unregisterStat(&d_conflict_inst);\r
-  StatisticsRegistry::unregisterStat(&d_prop_inst);\r
-  StatisticsRegistry::unregisterStat(&d_entailment_checks);\r
-}\r
-\r
-TNode QuantConflictFind::getZero( Kind k ) {\r
-  std::map< Kind, Node >::iterator it = d_zero.find( k );\r
-  if( it==d_zero.end() ){\r
-    Node nn;\r
-    if( k==PLUS ){\r
-      nn = NodeManager::currentNM()->mkConst( Rational(0) );\r
-    }\r
-    d_zero[k] = nn;\r
-    return nn;\r
-  }else{\r
-    return it->second;\r
-  }\r
-}\r
-\r
-\r
-}\r
+/*********************                                                        */
+/*! \file quant_conflict_find.cpp
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief quant conflict find class
+ **
+ **/
+
+#include <vector>
+
+#include "theory/quantifiers/quant_conflict_find.h"
+#include "theory/quantifiers/quant_util.h"
+#include "theory/theory_engine.h"
+#include "theory/quantifiers/options.h"
+#include "theory/quantifiers/term_database.h"
+#include "theory/quantifiers/trigger.h"
+
+using namespace CVC4;
+using namespace CVC4::kind;
+using namespace CVC4::theory;
+using namespace CVC4::theory::quantifiers;
+using namespace std;
+
+namespace CVC4 {
+
+
+
+void QuantInfo::initialize( Node q, Node qn ) {
+  d_q = q;
+  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+    d_match.push_back( TNode::null() );
+    d_match_term.push_back( TNode::null() );
+  }
+
+  //register the variables
+  for( unsigned i=0; i<q[0].getNumChildren(); i++ ){
+    d_var_num[q[0][i]] = i;
+    d_vars.push_back( q[0][i] );
+    d_var_types.push_back( q[0][i].getType() );
+  }
+
+  registerNode( qn, true, true );
+
+
+  Trace("qcf-qregister") << "- Make match gen structure..." << std::endl;
+  d_mg = new MatchGen( this, qn );
+
+  if( d_mg->isValid() ){
+    /*
+    for( unsigned j=0; j<q[0].getNumChildren(); j++ ){
+      if( d_inMatchConstraint.find( q[0][j] )==d_inMatchConstraint.end() ){
+        Trace("qcf-invalid") << "QCF invalid : variable " << q[0][j] << " does not exist in a matching constraint." << std::endl;
+        d_mg->setInvalid();
+        break;
+      }
+    }
+    */
+    if( d_mg->isValid() ){
+      for( unsigned j=q[0].getNumChildren(); j<d_vars.size(); j++ ){
+        if( d_vars[j].getKind()!=BOUND_VARIABLE ){
+          d_var_mg[j] = NULL;
+          bool is_tsym = false;
+          if( !MatchGen::isHandledUfTerm( d_vars[j] ) && d_vars[j].getKind()!=ITE ){
+            is_tsym = true;
+            d_tsym_vars.push_back( j );
+          }
+          if( !is_tsym || options::qcfTConstraint() ){
+            d_var_mg[j] = new MatchGen( this, d_vars[j], true );
+          }
+          if( !d_var_mg[j] || !d_var_mg[j]->isValid() ){
+            Trace("qcf-invalid") << "QCF invalid : cannot match for " << d_vars[j] << std::endl;
+            d_mg->setInvalid();
+            break;
+          }else{
+            std::vector< int > bvars;
+            d_var_mg[j]->determineVariableOrder( this, bvars );
+          }
+        }
+      }
+      if( d_mg->isValid() ){
+        std::vector< int > bvars;
+        d_mg->determineVariableOrder( this, bvars );
+      }
+    }
+  }else{
+    Trace("qcf-invalid") << "QCF invalid : body of formula cannot be processed." << std::endl;
+  }
+  Trace("qcf-qregister-summary") << "QCF register : " << ( d_mg->isValid() ? "VALID " : "INVALID" ) << " : " << q << std::endl;
+}
+
+void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant ) {
+  Trace("qcf-qregister-debug2") << "Register : " << n << std::endl;
+  if( n.getKind()==FORALL ){
+    registerNode( n[1], hasPol, pol, true );
+  }else{
+    if( !MatchGen::isHandledBoolConnective( n ) ){
+      if( n.hasBoundVar() ){
+        //literals
+        if( n.getKind()==EQUAL ){
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){
+            flatten( n[i], beneathQuant );
+          }
+        }else if( MatchGen::isHandledUfTerm( n ) ){
+          flatten( n, beneathQuant );
+        }else if( n.getKind()==ITE ){
+          for( unsigned i=1; i<=2; i++ ){
+            flatten( n[i], beneathQuant );
+          }
+          registerNode( n[0], false, pol, beneathQuant );
+        }else if( options::qcfTConstraint() ){
+          //a theory-specific predicate
+          for( unsigned i=0; i<n.getNumChildren(); i++ ){
+            flatten( n[i], beneathQuant );
+          }
+        }
+      }
+    }else{
+      for( unsigned i=0; i<n.getNumChildren(); i++ ){
+        bool newHasPol;
+        bool newPol;
+        QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );
+        //QcfNode * qcfc = new QcfNode( d_c );
+        //qcfc->d_parent = qcf;
+        //qcf->d_child[i] = qcfc;
+        registerNode( n[i], newHasPol, newPol, beneathQuant );
+      }
+    }
+  }
+}
+
+void QuantInfo::flatten( Node n, bool beneathQuant ) {
+  Trace("qcf-qregister-debug2") << "Flatten : " << n << std::endl;
+  if( n.hasBoundVar() ){
+    if( n.getKind()==BOUND_VARIABLE ){
+      d_inMatchConstraint[n] = true;
+    }
+    //if( MatchGen::isHandledUfTerm( n ) || n.getKind()==ITE ){
+    if( d_var_num.find( n )==d_var_num.end() ){
+      Trace("qcf-qregister-debug2") << "Add FLATTEN VAR : " << n << std::endl;
+      d_var_num[n] = d_vars.size();
+      d_vars.push_back( n );
+      d_var_types.push_back( n.getType() );
+      d_match.push_back( TNode::null() );
+      d_match_term.push_back( TNode::null() );
+      if( n.getKind()==ITE ){
+        registerNode( n, false, false );
+      }else{
+        for( unsigned i=0; i<n.getNumChildren(); i++ ){
+          flatten( n[i], beneathQuant );
+        }
+      }
+    }else{
+      Trace("qcf-qregister-debug2") << "...already processed" << std::endl;
+    }
+  }else{
+    Trace("qcf-qregister-debug2") << "...is ground." << std::endl;
+  }
+}
+
+
+void QuantInfo::reset_round( QuantConflictFind * p ) {
+  for( unsigned i=0; i<d_match.size(); i++ ){
+    d_match[i] = TNode::null();
+    d_match_term[i] = TNode::null();
+  }
+  d_curr_var_deq.clear();
+  d_tconstraints.clear();
+  //add built-in variable constraints
+  for( unsigned r=0; r<2; r++ ){
+    for( std::map< int, std::vector< Node > >::iterator it = d_var_constraint[r].begin();
+         it != d_var_constraint[r].end(); ++it ){
+      for( unsigned j=0; j<it->second.size(); j++ ){
+        Node rr = it->second[j];
+        if( !isVar( rr ) ){
+          rr = p->getRepresentative( rr );
+        }
+        if( addConstraint( p, it->first, rr, r==0 )==-1 ){
+          d_var_constraint[0].clear();
+          d_var_constraint[1].clear();
+          //quantified formula is actually equivalent to true
+          Trace("qcf-qregister") << "Quantifier is equivalent to true!!!" << std::endl;
+          d_mg->d_children.clear();
+          d_mg->d_n = NodeManager::currentNM()->mkConst( true );
+          d_mg->d_type = MatchGen::typ_ground;
+          return;
+        }
+      }
+    }
+  }
+  d_mg->reset_round( p );
+  for( std::map< int, MatchGen * >::iterator it = d_var_mg.begin(); it != d_var_mg.end(); ++it ){
+    it->second->reset_round( p );
+  }
+  //now, reset for matching
+  d_mg->reset( p, false, this );
+}
+
+int QuantInfo::getCurrentRepVar( int v ) {
+  if( v!=-1 && !d_match[v].isNull() ){
+    int vn = getVarNum( d_match[v] );
+    if( vn!=-1 ){
+      //int vr = getCurrentRepVar( vn );
+      //d_match[v] = d_vars[vr];
+      //return vr;
+      return getCurrentRepVar( vn );
+    }
+  }
+  return v;
+}
+
+TNode QuantInfo::getCurrentValue( TNode n ) {
+  int v = getVarNum( n );
+  if( v==-1 ){
+    return n;
+  }else{
+    if( d_match[v].isNull() ){
+      return n;
+    }else{
+      Assert( getVarNum( d_match[v] )!=v );
+      return getCurrentValue( d_match[v] );
+    }
+  }
+}
+
+TNode QuantInfo::getCurrentExpValue( TNode n ) {
+  int v = getVarNum( n );
+  if( v==-1 ){
+    return n;
+  }else{
+    if( d_match[v].isNull() ){
+      return n;
+    }else{
+      Assert( getVarNum( d_match[v] )!=v );
+      if( d_match_term[v].isNull() ){
+        return getCurrentValue( d_match[v] );
+      }else{
+        return d_match_term[v];
+      }
+    }
+  }
+}
+
+bool QuantInfo::getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq ) {
+  //check disequalities
+  std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );
+  if( itd!=d_curr_var_deq.end() ){
+    for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
+      Node cv = getCurrentValue( it->first );
+      Debug("qcf-ccbe") << "compare " << cv << " " << n << std::endl;
+      if( cv==n ){
+        return false;
+      }else if( chDiseq && !isVar( n ) && !isVar( cv ) ){
+        //they must actually be disequal if we are looking for conflicts
+        if( !p->areDisequal( n, cv ) ){
+          //TODO : check for entailed disequal
+
+          return false;
+        }
+      }
+    }
+  }
+  return true;
+}
+
+int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity ) {
+  v = getCurrentRepVar( v );
+  int vn = getVarNum( n );
+  vn = vn==-1 ? -1 : getCurrentRepVar( vn );
+  n = getCurrentValue( n );
+  return addConstraint( p, v, n, vn, polarity, false );
+}
+
+int QuantInfo::addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove ) {
+  //for handling equalities between variables, and disequalities involving variables
+  Debug("qcf-match-debug") << "- " << (doRemove ? "un" : "" ) << "constrain : " << v << " -> " << n << " (cv=" << getCurrentValue( n ) << ")";
+  Debug("qcf-match-debug") << ", (vn=" << vn << "), polarity = " << polarity << std::endl;
+  Assert( doRemove || n==getCurrentValue( n ) );
+  Assert( doRemove || v==getCurrentRepVar( v ) );
+  Assert( doRemove || vn==getCurrentRepVar( getVarNum( n ) ) );
+  if( polarity ){
+    if( vn!=v ){
+      if( doRemove ){
+        if( vn!=-1 ){
+          //if set to this in the opposite direction, clean up opposite instead
+          //          std::map< int, TNode >::iterator itmn = d_match.find( vn );
+          if( d_match[vn]==d_vars[v] ){
+            return addConstraint( p, vn, d_vars[v], v, true, true );
+          }else{
+            //unsetting variables equal
+            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( vn );
+            if( itd!=d_curr_var_deq.end() ){
+              //remove disequalities owned by this
+              std::vector< TNode > remDeq;
+              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
+                if( it->second==v ){
+                  remDeq.push_back( it->first );
+                }
+              }
+              for( unsigned i=0; i<remDeq.size(); i++ ){
+                d_curr_var_deq[vn].erase( remDeq[i] );
+              }
+            }
+          }
+        }
+        d_match[v] = TNode::null();
+        return 1;
+      }else{
+        //std::map< int, TNode >::iterator itm = d_match.find( v );
+
+        if( vn!=-1 ){
+          Debug("qcf-match-debug") << "  ...Variable bound to variable" << std::endl;
+          //std::map< int, TNode >::iterator itmn = d_match.find( vn );
+          if( d_match[v].isNull() ){
+            //setting variables equal
+            bool alreadySet = false;
+            if( !d_match[vn].isNull() ){
+              alreadySet = true;
+              Assert( !isVar( d_match[vn] ) );
+            }
+
+            //copy or check disequalities
+            std::map< int, std::map< TNode, int > >::iterator itd = d_curr_var_deq.find( v );
+            if( itd!=d_curr_var_deq.end() ){
+              for( std::map< TNode, int >::iterator it = itd->second.begin(); it != itd->second.end(); ++it ){
+                Node dv = getCurrentValue( it->first );
+                if( !alreadySet ){
+                  if( d_curr_var_deq[vn].find( dv )==d_curr_var_deq[vn].end() ){
+                    d_curr_var_deq[vn][dv] = v;
+                  }
+                }else{
+                  if( !p->areMatchDisequal( d_match[vn], dv ) ){
+                    Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
+                    return -1;
+                  }
+                }
+              }
+            }
+            if( alreadySet ){
+              n = getCurrentValue( n );
+            }
+          }else{
+            if( d_match[vn].isNull() ){
+              Debug("qcf-match-debug") << " ...Reverse direction" << std::endl;
+              //set the opposite direction
+              return addConstraint( p, vn, d_vars[v], v, true, false );
+            }else{
+              Debug("qcf-match-debug") << "  -> Both variables bound, compare" << std::endl;
+              //are they currently equal
+              return p->areMatchEqual( d_match[v], d_match[vn] ) ? 0 : -1;
+            }
+          }
+        }else{
+          Debug("qcf-match-debug") << "  ...Variable bound to ground" << std::endl;
+          if( d_match[v].isNull() ){
+          }else{
+            //compare ground values
+            Debug("qcf-match-debug") << "  -> Ground value, compare " << d_match[v] << " "<< n << std::endl;
+            return p->areMatchEqual( d_match[v], n ) ? 0 : -1;
+          }
+        }
+        if( setMatch( p, v, n ) ){
+          Debug("qcf-match-debug") << "  -> success" << std::endl;
+          return 1;
+        }else{
+          Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
+          return -1;
+        }
+      }
+    }else{
+      Debug("qcf-match-debug") << "  -> redundant, variable identity" << std::endl;
+      return 0;
+    }
+  }else{
+    if( vn==v ){
+      Debug("qcf-match-debug") << "  -> fail, variable identity" << std::endl;
+      return -1;
+    }else{
+      if( doRemove ){
+        Assert( d_curr_var_deq[v].find( n )!=d_curr_var_deq[v].end() );
+        d_curr_var_deq[v].erase( n );
+        return 1;
+      }else{
+        if( d_curr_var_deq[v].find( n )==d_curr_var_deq[v].end() ){
+          //check if it respects equality
+          //std::map< int, TNode >::iterator itm = d_match.find( v );
+          if( !d_match[v].isNull() ){
+            TNode nv = getCurrentValue( n );
+            if( !p->areMatchDisequal( nv, d_match[v] ) ){
+              Debug("qcf-match-debug") << "  -> fail, conflicting disequality" << std::endl;
+              return -1;
+            }
+          }
+          d_curr_var_deq[v][n] = v;
+          Debug("qcf-match-debug") << "  -> success" << std::endl;
+          return 1;
+        }else{
+          Debug("qcf-match-debug") << "  -> redundant disequality" << std::endl;
+          return 0;
+        }
+      }
+    }
+  }
+}
+
+bool QuantInfo::isConstrainedVar( int v ) {
+  if( d_curr_var_deq.find( v )!=d_curr_var_deq.end() && !d_curr_var_deq[v].empty() ){
+    return true;
+  }else{
+    Node vv = getVar( v );
+    //for( std::map< int, TNode >::iterator it = d_match.begin(); it != d_match.end(); ++it ){
+    for( unsigned i=0; i<d_match.size(); i++ ){
+      if( d_match[i]==vv ){
+        return true;
+      }
+    }
+    for( std::map< int, std::map< TNode, int > >::iterator it = d_curr_var_deq.begin(); it != d_curr_var_deq.end(); ++it ){
+      for( std::map< TNode, int >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){
+        if( it2->first==vv ){
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
+
+bool QuantInfo::setMatch( QuantConflictFind * p, int v, TNode n ) {
+  if( getCurrentCanBeEqual( p, v, n ) ){
+    Debug("qcf-match-debug") << "-- bind : " << v << " -> " << n << ", checked " <<  d_curr_var_deq[v].size() << " disequalities" << std::endl;
+    d_match[v] = n;
+    return true;
+  }else{
+    return false;
+  }
+}
+
+bool QuantInfo::isMatchSpurious( QuantConflictFind * p ) {
+  for( int i=0; i<getNumVars(); i++ ){
+    //std::map< int, TNode >::iterator it = d_match.find( i );
+    if( !d_match[i].isNull() ){
+      if( !getCurrentCanBeEqual( p, i, d_match[i], p->d_effort==QuantConflictFind::effort_conflict ) ){
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool QuantInfo::isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms ) {
+  if( !d_tconstraints.empty() ){
+    //check constraints
+    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){
+      //apply substitution to the tconstraint
+      Node cons = it->first.substitute( p->getTermDatabase()->d_vars[d_q].begin(),
+                                        p->getTermDatabase()->d_vars[d_q].end(),
+                                        terms.begin(), terms.end() );
+      cons = it->second ? cons : cons.negate();
+      if( !entailmentTest( p, cons, p->d_effort==QuantConflictFind::effort_conflict ) ){
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool QuantInfo::entailmentTest( QuantConflictFind * p, Node lit, bool chEnt ) {
+  Trace("qcf-tconstraint-debug") << "Check : " << lit << std::endl;
+  Node rew = Rewriter::rewrite( lit );
+  if( rew==p->d_false ){
+    Trace("qcf-tconstraint-debug") << "...constraint " << lit << " is disentailed (rewrites to false)." << std::endl;
+    return false;
+  }else if( rew!=p->d_true ){
+    //if checking for conflicts, we must be sure that the constraint is entailed
+    if( chEnt ){
+      //check if it is entailed
+      Trace("qcf-tconstraint-debug") << "Check entailment of " << rew << "..." << std::endl;
+      std::pair<bool, Node> et = p->getQuantifiersEngine()->getTheoryEngine()->entailmentCheck(THEORY_OF_TYPE_BASED, rew );
+      ++(p->d_statistics.d_entailment_checks);
+      Trace("qcf-tconstraint-debug") << "ET result : " << et.first << " " << et.second << std::endl;
+      if( !et.first ){
+        Trace("qcf-tconstraint-debug") << "...cannot show entailment of " << rew << "." << std::endl;
+        return false;
+      }else{
+        return true;
+      }
+    }else{
+      Trace("qcf-tconstraint-debug") << "...does not need to be entailed." << std::endl;
+      return true;
+    }
+  }else{
+    Trace("qcf-tconstraint-debug") << "...rewrites to true." << std::endl;
+    return true;
+  }
+}
+
+bool QuantInfo::completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue ) {
+  //assign values for variables that were unassigned (usually not necessary, but handles corner cases)
+  bool doFail = false;
+  bool success = true;
+  if( doContinue ){
+    doFail = true;
+    success = false;
+  }else{
+    //solve for interpreted symbol matches
+    //   this breaks the invariant that all introduced constraints are over existing terms
+    for( int i=(int)(d_tsym_vars.size()-1); i>=0; i-- ){
+      int index = d_tsym_vars[i];
+      TNode v = getCurrentValue( d_vars[index] );
+      int slv_v = -1;
+      if( v==d_vars[index] ){
+        slv_v = index;
+      }
+      Trace("qcf-tconstraint-debug") << "Solve " << d_vars[index] << " = " << v << " " << d_vars[index].getKind() << std::endl;
+      if( d_vars[index].getKind()==PLUS || d_vars[index].getKind()==MULT ){
+        Kind k = d_vars[index].getKind();
+        std::vector< TNode > children;
+        for( unsigned j=0; j<d_vars[index].getNumChildren(); j++ ){
+          int vn = getVarNum( d_vars[index][j] );
+          if( vn!=-1 ){
+            TNode vv = getCurrentValue( d_vars[index][j] );
+            if( vv==d_vars[index][j] ){
+              //we will assign this
+              if( slv_v==-1 ){
+                Trace("qcf-tconstraint-debug") << "...will solve for var #" << vn << std::endl;
+                slv_v = vn;
+                if( p->d_effort!=QuantConflictFind::effort_conflict ){
+                  break;
+                }
+              }else{
+                Node z = p->getZero( k );
+                if( !z.isNull() ){
+                  Trace("qcf-tconstraint-debug") << "...set " << d_vars[vn] << " = " << z << std::endl;
+                  assigned.push_back( vn );
+                  if( !setMatch( p, vn, z ) ){
+                    success = false;
+                    break;
+                  }
+                }
+              }
+            }else{
+              Trace("qcf-tconstraint-debug") << "...sum value " << vv << std::endl;
+              children.push_back( vv );
+            }
+          }else{
+            Trace("qcf-tconstraint-debug") << "...sum " << d_vars[index][j] << std::endl;
+            children.push_back( d_vars[index][j] );
+          }
+        }
+        if( success ){
+          if( slv_v!=-1 ){
+            Node lhs;
+            if( children.empty() ){
+              lhs = p->getZero( k );
+            }else if( children.size()==1 ){
+              lhs = children[0];
+            }else{
+              lhs = NodeManager::currentNM()->mkNode( k, children );
+            }
+            Node sum;
+            if( v==d_vars[index] ){
+              sum = lhs;
+            }else{
+              if( p->d_effort==QuantConflictFind::effort_conflict ){
+                Kind kn = k;
+                if( d_vars[index].getKind()==PLUS ){
+                  kn = MINUS;
+                }
+                if( kn!=k ){
+                  sum = NodeManager::currentNM()->mkNode( kn, v, lhs );
+                }
+              }
+            }
+            if( !sum.isNull() ){
+              assigned.push_back( slv_v );
+              Trace("qcf-tconstraint-debug") << "...set " << d_vars[slv_v] << " = " << sum << std::endl;
+              if( !setMatch( p, slv_v, sum ) ){
+                success = false;
+              }
+              p->d_tempCache.push_back( sum );
+            }
+          }else{
+            //must show that constraint is met
+            Node sum = NodeManager::currentNM()->mkNode( k, children );
+            Node eq = sum.eqNode( v );
+            if( !entailmentTest( p, eq ) ){
+              success = false;
+            }
+            p->d_tempCache.push_back( sum );
+          }
+        }
+      }
+
+      if( !success ){
+        break;
+      }
+    }
+    if( success ){
+      //check what is left to assign
+      d_unassigned.clear();
+      d_unassigned_tn.clear();
+      std::vector< int > unassigned[2];
+      std::vector< TypeNode > unassigned_tn[2];
+      for( int i=0; i<getNumVars(); i++ ){
+        if( d_match[i].isNull() ){
+          int rindex = d_var_mg.find( i )==d_var_mg.end() ? 1 : 0;
+          unassigned[rindex].push_back( i );
+          unassigned_tn[rindex].push_back( getVar( i ).getType() );
+          assigned.push_back( i );
+        }
+      }
+      d_unassigned_nvar = unassigned[0].size();
+      for( unsigned i=0; i<2; i++ ){
+        d_unassigned.insert( d_unassigned.end(), unassigned[i].begin(), unassigned[i].end() );
+        d_unassigned_tn.insert( d_unassigned_tn.end(), unassigned_tn[i].begin(), unassigned_tn[i].end() );
+      }
+      d_una_eqc_count.clear();
+      d_una_index = 0;
+    }
+  }
+
+  if( !d_unassigned.empty() && ( success || doContinue ) ){
+    Trace("qcf-check") << "Assign to unassigned..." << std::endl;
+    do {
+      if( doFail ){
+        Trace("qcf-check-unassign") << "Failure, try again..." << std::endl;
+      }
+      bool invalidMatch = false;
+      while( ( d_una_index>=0 && (int)d_una_index<(int)d_unassigned.size() ) || invalidMatch || doFail ){
+        invalidMatch = false;
+        if( !doFail && d_una_index==(int)d_una_eqc_count.size() ){
+          //check if it has now been assigned
+          if( d_una_index<d_unassigned_nvar ){
+            if( !isConstrainedVar( d_unassigned[d_una_index] ) ){
+              d_una_eqc_count.push_back( -1 );
+            }else{
+              d_var_mg[ d_unassigned[d_una_index] ]->reset( p, true, this );
+              d_una_eqc_count.push_back( 0 );
+            }
+          }else{
+            d_una_eqc_count.push_back( 0 );
+          }
+        }else{
+          bool failed = false;
+          if( !doFail ){
+            if( d_una_index<d_unassigned_nvar ){
+              if( !isConstrainedVar( d_unassigned[d_una_index] ) ){
+                Trace("qcf-check-unassign") << "Succeeded, variable unconstrained at " << d_una_index << std::endl;
+                d_una_index++;
+              }else if( d_var_mg[d_unassigned[d_una_index]]->getNextMatch( p, this ) ){
+                Trace("qcf-check-unassign") << "Succeeded match with mg at " << d_una_index << std::endl;
+                d_una_index++;
+              }else{
+                failed = true;
+                Trace("qcf-check-unassign") << "Failed match with mg at " << d_una_index << std::endl;
+              }
+            }else{
+              Assert( doFail || d_una_index==(int)d_una_eqc_count.size()-1 );
+              if( d_una_eqc_count[d_una_index]<(int)p->d_eqcs[d_unassigned_tn[d_una_index]].size() ){
+                int currIndex = d_una_eqc_count[d_una_index];
+                d_una_eqc_count[d_una_index]++;
+                Trace("qcf-check-unassign") << d_unassigned[d_una_index] << "->" << p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] << std::endl;
+                if( setMatch( p, d_unassigned[d_una_index], p->d_eqcs[d_unassigned_tn[d_una_index]][currIndex] ) ){
+                  d_match_term[d_unassigned[d_una_index]] = TNode::null();
+                  Trace("qcf-check-unassign") << "Succeeded match " << d_una_index << std::endl;
+                  d_una_index++;
+                }else{
+                  Trace("qcf-check-unassign") << "Failed match " << d_una_index << std::endl;
+                  invalidMatch = true;
+                }
+              }else{
+                failed = true;
+                Trace("qcf-check-unassign") << "No more matches " << d_una_index << std::endl;
+              }
+            }
+          }
+          if( doFail || failed ){
+            do{
+              if( !doFail ){
+                d_una_eqc_count.pop_back();
+              }else{
+                doFail = false;
+              }
+              d_una_index--;
+            }while( d_una_index>=0 && d_una_eqc_count[d_una_index]==-1 );
+          }
+        }
+      }
+      success = d_una_index>=0;
+      if( success ){
+        doFail = true;
+        Trace("qcf-check-unassign") << "  Try: " << std::endl;
+        for( unsigned i=0; i<d_unassigned.size(); i++ ){
+          int ui = d_unassigned[i];
+          if( !d_match[ui].isNull() ){
+            Trace("qcf-check-unassign") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;
+          }
+        }
+      }
+    }while( success && isMatchSpurious( p ) );
+  }
+  if( success ){
+    for( unsigned i=0; i<d_unassigned.size(); i++ ){
+      int ui = d_unassigned[i];
+      if( !d_match[ui].isNull() ){
+        Trace("qcf-check") << "  Assigned #" << ui << " : " << d_vars[ui] << " -> " << d_match[ui] << std::endl;
+      }
+    }
+    return true;
+  }else{
+    for( unsigned i=0; i<assigned.size(); i++ ){
+      d_match[ assigned[i] ] = TNode::null();
+    }
+    assigned.clear();
+    return false;
+  }
+}
+
+void QuantInfo::getMatch( std::vector< Node >& terms ){
+  for( unsigned i=0; i<d_q[0].getNumChildren(); i++ ){
+    //Node cv = qi->getCurrentValue( qi->d_match[i] );
+    int repVar = getCurrentRepVar( i );
+    Node cv;
+    //std::map< int, TNode >::iterator itmt = qi->d_match_term.find( repVar );
+    if( !d_match_term[repVar].isNull() ){
+      cv = d_match_term[repVar];
+    }else{
+      cv = d_match[repVar];
+    }
+    Debug("qcf-check-inst") << "INST : " << i << " -> " << cv << ", from " << d_match[i] << std::endl;
+    terms.push_back( cv );
+  }
+}
+
+void QuantInfo::revertMatch( std::vector< int >& assigned ) {
+  for( unsigned i=0; i<assigned.size(); i++ ){
+    d_match[ assigned[i] ] = TNode::null();
+  }
+}
+
+void QuantInfo::debugPrintMatch( const char * c ) {
+  for( int i=0; i<getNumVars(); i++ ){
+    Trace(c) << "  " << d_vars[i] << " -> ";
+    if( !d_match[i].isNull() ){
+      Trace(c) << d_match[i];
+    }else{
+      Trace(c) << "(unassigned) ";
+    }
+    if( !d_curr_var_deq[i].empty() ){
+      Trace(c) << ", DEQ{ ";
+      for( std::map< TNode, int >::iterator it = d_curr_var_deq[i].begin(); it != d_curr_var_deq[i].end(); ++it ){
+        Trace(c) << it->first << " ";
+      }
+      Trace(c) << "}";
+    }
+    if( !d_match_term[i].isNull() && d_match_term[i]!=d_match[i] ){
+      Trace(c) << ", EXP : " << d_match_term[i];
+    }
+    Trace(c) <<  std::endl;
+  }
+  if( !d_tconstraints.empty() ){
+    Trace(c) << "ADDITIONAL CONSTRAINTS : " << std::endl;
+    for( std::map< Node, bool >::iterator it = d_tconstraints.begin(); it != d_tconstraints.end(); ++it ){
+      Trace(c) << "   " << it->first << " -> " << it->second << std::endl;
+    }
+  }
+}
+
+MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar ){
+  Trace("qcf-qregister-debug") << "Make match gen for " << n << ", isVar = " << isVar << std::endl;
+  std::vector< Node > qni_apps;
+  d_qni_size = 0;
+  if( isVar ){
+    Assert( qi->d_var_num.find( n )!=qi->d_var_num.end() );
+    if( n.getKind()==ITE ){
+      d_type = typ_ite_var;
+      d_type_not = false;
+      d_n = n;
+      d_children.push_back( MatchGen( qi, d_n[0] ) );
+      if( d_children[0].isValid() ){
+        d_type = typ_ite_var;
+        for( unsigned i=1; i<=2; i++ ){
+          Node nn = n.eqNode( n[i] );
+          d_children.push_back( MatchGen( qi, nn ) );
+          d_children[d_children.size()-1].d_qni_bound_except.push_back( 0 );
+          if( !d_children[d_children.size()-1].isValid() ){
+            setInvalid();
+            break;
+          }
+        }
+      }else{
+        d_type = typ_invalid;
+      }
+    }else{
+      d_type = isHandledUfTerm( n ) ? typ_var : typ_tsym;
+      d_qni_var_num[0] = qi->getVarNum( n );
+      d_qni_size++;
+      d_type_not = false;
+      d_n = n;
+      //Node f = getOperator( n );
+      for( unsigned j=0; j<d_n.getNumChildren(); j++ ){
+        Node nn = d_n[j];
+        Trace("qcf-qregister-debug") << "  " << d_qni_size;
+        if( qi->isVar( nn ) ){
+          int v = qi->d_var_num[nn];
+          Trace("qcf-qregister-debug") << " is var #" << v << std::endl;
+          d_qni_var_num[d_qni_size] = v;
+          //qi->addFuncParent( v, f, j );
+        }else{
+          Trace("qcf-qregister-debug") << " is gterm " << nn << std::endl;
+          d_qni_gterm[d_qni_size] = nn;
+        }
+        d_qni_size++;
+      }
+    }
+  }else{
+    if( n.hasBoundVar() ){
+      d_type_not = false;
+      d_n = n;
+      if( d_n.getKind()==NOT ){
+        d_n = d_n[0];
+        d_type_not = !d_type_not;
+      }
+
+      if( isHandledBoolConnective( d_n ) ){
+        //non-literals
+        d_type = typ_formula;
+        for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
+          if( d_n.getKind()!=FORALL || i==1 ){
+            d_children.push_back( MatchGen( qi, d_n[i], false ) );
+            if( !d_children[d_children.size()-1].isValid() ){
+              setInvalid();
+              break;
+            }
+          }
+          /*
+          else if( isTop && n.getKind()==OR && d_children[d_children.size()-1].d_type==typ_var_eq ){
+            Trace("qcf-qregister-debug") << "Remove child, make built-in constraint" << std::endl;
+            //if variable equality/disequality at top level, remove immediately
+            bool cIsNot = d_children[d_children.size()-1].d_type_not;
+            Node cn = d_children[d_children.size()-1].d_n;
+            Assert( cn.getKind()==EQUAL );
+            Assert( p->d_qinfo[q].isVar( cn[0] ) || p->d_qinfo[q].isVar( cn[1] ) );
+            //make it a built-in constraint instead
+            for( unsigned i=0; i<2; i++ ){
+              if( p->d_qinfo[q].isVar( cn[i] ) ){
+                int v = p->d_qinfo[q].getVarNum( cn[i] );
+                Node cno = cn[i==0 ? 1 : 0];
+                p->d_qinfo[q].d_var_constraint[ cIsNot ? 0 : 1 ][v].push_back( cno );
+                break;
+              }
+            }
+            d_children.pop_back();
+          }
+          */
+        }
+      }else{
+        d_type = typ_invalid;
+        //literals
+        if( isHandledUfTerm( d_n ) ){
+          Assert( qi->isVar( d_n ) );
+          d_type = typ_pred;
+        }else if( d_n.getKind()==BOUND_VARIABLE ){
+          Assert( d_n.getType().isBoolean() );
+          d_type = typ_bool_var;
+        }else if( d_n.getKind()==EQUAL || options::qcfTConstraint() ){
+          for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
+            if( d_n[i].hasBoundVar() ){
+              if( !qi->isVar( d_n[i] ) ){
+                Trace("qcf-qregister-debug")  << "ERROR : not var " << d_n[i] << std::endl;
+              }
+              Assert( qi->isVar( d_n[i] ) );
+              if( d_n.getKind()!=EQUAL && qi->isVar( d_n[i] ) ){
+                d_qni_var_num[i+1] = qi->d_var_num[d_n[i]];
+              }
+            }else{
+              d_qni_gterm[i] = d_n[i];
+            }
+          }
+          d_type = d_n.getKind()==EQUAL ? typ_eq : typ_tconstraint;
+          Trace("qcf-tconstraint") << "T-Constraint : " << d_n << std::endl;
+        }
+      }
+    }else{
+      //we will just evaluate
+      d_n = n;
+      d_type = typ_ground;
+    }
+    //if( d_type!=typ_invalid ){
+      //determine an efficient children ordering
+      //if( !d_children.empty() ){
+        //for( unsigned i=0; i<d_children.size(); i++ ){
+        //  d_children_order.push_back( i );
+        //}
+        //if( !d_n.isNull() && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF ) ){
+          //sort based on the type of the constraint : ground comes first, then literals, then others
+          //MatchGenSort mgs;
+          //mgs.d_mg = this;
+          //std::sort( d_children_order.begin(), d_children_order.end(), mgs );
+        //}
+      //}
+    //}
+  }
+  Trace("qcf-qregister-debug")  << "Done make match gen " << n << ", type = ";
+  debugPrintType( "qcf-qregister-debug", d_type, true );
+  Trace("qcf-qregister-debug") << std::endl;
+  //Assert( d_children.size()==d_children_order.size() );
+
+}
+
+void MatchGen::collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars ) {
+  int v = qi->getVarNum( n );
+  if( v!=-1 && std::find( cbvars.begin(), cbvars.end(), v )==cbvars.end() ){
+    cbvars.push_back( v );
+  }
+  for( unsigned i=0; i<n.getNumChildren(); i++ ){
+    collectBoundVar( qi, n[i], cbvars );
+  }
+}
+
+void MatchGen::determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars ) {
+  Trace("qcf-qregister-debug") << "Determine variable order " << d_n << std::endl;
+  bool isCom = d_type==typ_formula && ( d_n.getKind()==OR || d_n.getKind()==AND || d_n.getKind()==IFF );
+  std::map< int, std::vector< int > > c_to_vars;
+  std::map< int, std::vector< int > > vars_to_c;
+  std::map< int, int > vb_count;
+  std::map< int, int > vu_count;
+  std::vector< bool > assigned;
+  Trace("qcf-qregister-debug") << "Calculate bound variables..." << std::endl;
+  for( unsigned i=0; i<d_children.size(); i++ ){
+    collectBoundVar( qi, d_children[i].d_n, c_to_vars[i] );
+    assigned.push_back( false );
+    vb_count[i] = 0;
+    vu_count[i] = 0;
+    for( unsigned j=0; j<c_to_vars[i].size(); j++ ){
+      int v = c_to_vars[i][j];
+      vars_to_c[v].push_back( i );
+      if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){
+        vu_count[i]++;
+        if( !isCom ){
+          bvars.push_back( v );
+        }
+      }else{
+        vb_count[i]++;
+      }
+    }
+  }
+  if( isCom ){
+    //children that bind the least number of unbound variables go first
+    do {
+      int min_score = -1;
+      int min_score_index = -1;
+      for( unsigned i=0; i<d_children.size(); i++ ){
+        if( !assigned[i] ){
+          int score = vu_count[i];
+          if( min_score==-1 || score<min_score ){
+            min_score = score;
+            min_score_index = i;
+          }
+        }
+      }
+      Trace("qcf-qregister-debug") << "...assign child " << min_score_index << "/" << d_children.size() << std::endl;
+      Assert( min_score_index!=-1 );
+      //add to children order
+      d_children_order.push_back( min_score_index );
+      assigned[min_score_index] = true;
+      //if( vb_count[min_score_index]==0 ){
+      //  d_independent.push_back( min_score_index );
+      //}
+      //determine order internal to children
+      d_children[min_score_index].determineVariableOrder( qi, bvars );
+      Trace("qcf-qregister-debug")  << "...bind variables" << std::endl;
+      //now, make it a bound variable
+      for( unsigned i=0; i<c_to_vars[min_score_index].size(); i++ ){
+        int v = c_to_vars[min_score_index][i];
+        if( std::find( bvars.begin(), bvars.end(), v )==bvars.end() ){
+          for( unsigned j=0; j<vars_to_c[v].size(); j++ ){
+            int vc = vars_to_c[v][j];
+            vu_count[vc]--;
+            vb_count[vc]++;
+          }
+          bvars.push_back( v );
+        }
+      }
+      Trace("qcf-qregister-debug") << "...done assign child " << min_score_index << std::endl;
+    }while( d_children_order.size()!=d_children.size() );
+    Trace("qcf-qregister-debug") << "Done assign variable ordering for " << d_n << std::endl;
+  }else{
+    for( unsigned i=0; i<d_children.size(); i++ ){
+      d_children_order.push_back( i );
+      d_children[i].determineVariableOrder( qi, bvars );
+    }
+  }
+}
+
+
+void MatchGen::reset_round( QuantConflictFind * p ) {
+  d_wasSet = false;
+  for( unsigned i=0; i<d_children.size(); i++ ){
+    d_children[i].reset_round( p );
+  }
+  for( std::map< int, TNode >::iterator it = d_qni_gterm.begin(); it != d_qni_gterm.end(); ++it ){
+    d_qni_gterm_rep[it->first] = p->getRepresentative( it->second );
+  }
+  if( d_type==typ_ground ){
+    int e = p->evaluate( d_n );
+    if( e==1 ){
+      d_ground_eval[0] = p->d_true;
+    }else if( e==-1 ){
+      d_ground_eval[0] = p->d_false;
+    }
+  }else if( d_type==typ_eq ){
+    for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
+      if( !d_n[i].hasBoundVar() ){
+        d_ground_eval[i] = p->evaluateTerm( d_n[i] );
+      }
+    }
+  }
+  d_qni_bound_cons.clear();
+  d_qni_bound_cons_var.clear();
+  d_qni_bound.clear();
+}
+
+void MatchGen::reset( QuantConflictFind * p, bool tgt, QuantInfo * qi ) {
+  d_tgt = d_type_not ? !tgt : tgt;
+  Debug("qcf-match") << "     Reset for : " << d_n << ", type : ";
+  debugPrintType( "qcf-match", d_type );
+  Debug("qcf-match") << ", tgt = " << d_tgt << ", children = " << d_children.size() << " " << d_children_order.size() << std::endl;
+  d_qn.clear();
+  d_qni.clear();
+  d_qni_bound.clear();
+  d_child_counter = -1;
+  d_tgt_orig = d_tgt;
+
+  //set up processing matches
+  if( d_type==typ_invalid ){
+    //do nothing
+  }else if( d_type==typ_ground ){
+    if( d_ground_eval[0]==( d_tgt ? p->d_true : p->d_false ) ){
+      d_child_counter = 0;
+    }
+  }else if( d_type==typ_bool_var ){
+    //get current value of the variable
+    TNode n = qi->getCurrentValue( d_n );
+    int vn = qi->getCurrentRepVar( qi->getVarNum( n ) );
+    if( vn==-1 ){
+      //evaluate the value, see if it is compatible
+      int e = p->evaluate( n );
+      if( ( e==1 && d_tgt ) || ( e==0 && !d_tgt ) ){
+        d_child_counter = 0;
+      }
+    }else{
+      //unassigned, set match to true/false
+      d_qni_bound[0] = vn;
+      qi->setMatch( p, vn, d_tgt ? p->d_true : p->d_false );
+      d_child_counter = 0;
+    }
+    if( d_child_counter==0 ){
+      d_qn.push_back( NULL );
+    }
+  }else if( d_type==typ_var ){
+    Assert( isHandledUfTerm( d_n ) );
+    Node f = getOperator( p, d_n );
+    Debug("qcf-match-debug") << "       reset: Var will match operators of " << f << std::endl;
+    TermArgTrie * qni = p->getTermDatabase()->getTermArgTrie( Node::null(), f );
+    if( qni!=NULL ){
+      d_qn.push_back( qni );
+    }
+    d_matched_basis = false;
+  }else if( d_type==typ_tsym || d_type==typ_tconstraint ){
+    for( std::map< int, int >::iterator it = d_qni_var_num.begin(); it != d_qni_var_num.end(); ++it ){
+      int repVar = qi->getCurrentRepVar( it->second );
+      if( qi->d_match[repVar].isNull() ){
+        Debug("qcf-match-debug") << "Force matching on child #" << it->first << ", which is var #" << repVar << std::endl;
+        d_qni_bound[it->first] = repVar;
+      }
+    }
+    d_qn.push_back( NULL );
+  }else if( d_type==typ_pred || d_type==typ_eq ){
+    //add initial constraint
+    Node nn[2];
+    int vn[2];
+    if( d_type==typ_pred ){
+      nn[0] = qi->getCurrentValue( d_n );
+      vn[0] = qi->getCurrentRepVar( qi->getVarNum( nn[0] ) );
+      nn[1] = p->getRepresentative( d_tgt ? p->d_true : p->d_false );
+      vn[1] = -1;
+      d_tgt = true;
+    }else{
+      for( unsigned i=0; i<2; i++ ){
+        TNode nc;
+        std::map< int, TNode >::iterator it = d_qni_gterm_rep.find( i );
+        if( it!=d_qni_gterm_rep.end() ){
+          nc = it->second;
+        }else{
+          nc = d_n[i];
+        }
+        nn[i] = qi->getCurrentValue( nc );
+        vn[i] = qi->getCurrentRepVar( qi->getVarNum( nn[i] ) );
+      }
+    }
+    bool success;
+    if( vn[0]==-1 && vn[1]==-1 ){
+      //Trace("qcf-explain") << "    reset : " << d_n << " check ground values " << nn[0] << " " << nn[1] << " (tgt=" << d_tgt << ")" << std::endl;
+      Debug("qcf-match-debug") << "       reset: check ground values " << nn[0] << " " << nn[1] << " (" << d_tgt << ")" << std::endl;
+      //just compare values
+      if( d_tgt ){
+        success = p->areMatchEqual( nn[0], nn[1] );
+      }else{
+        if( p->d_effort==QuantConflictFind::effort_conflict ){
+          success = p->areDisequal( nn[0], nn[1] );
+        }else{
+          success = p->areMatchDisequal( nn[0], nn[1] );
+        }
+      }
+    }else{
+      //otherwise, add a constraint to a variable
+      if( vn[1]!=-1 && vn[0]==-1 ){
+        //swap
+        Node t = nn[1];
+        nn[1] = nn[0];
+        nn[0] = t;
+        vn[0] = vn[1];
+        vn[1] = -1;
+      }
+      Debug("qcf-match-debug") << "       reset: add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << std::endl;
+      //add some constraint
+      int addc = qi->addConstraint( p, vn[0], nn[1], vn[1], d_tgt, false );
+      success = addc!=-1;
+      //if successful and non-redundant, store that we need to cleanup this
+      if( addc==1 ){
+        //Trace("qcf-explain") << "       reset: " << d_n << " add constraint " << vn[0] << " -> " << nn[1] << " (vn=" << vn[1] << ")" << ", d_tgt = " << d_tgt << std::endl;
+        for( unsigned i=0; i<2; i++ ){
+          if( vn[i]!=-1 && std::find( d_qni_bound_except.begin(), d_qni_bound_except.end(), i )==d_qni_bound_except.end() ){
+            d_qni_bound[vn[i]] = vn[i];
+          }
+        }
+        d_qni_bound_cons[vn[0]] = nn[1];
+        d_qni_bound_cons_var[vn[0]] = vn[1];
+      }
+    }
+    //if successful, we will bind values to variables
+    if( success ){
+      d_qn.push_back( NULL );
+    }
+  }else{
+    if( d_children.empty() ){
+      //add dummy
+      d_qn.push_back( NULL );
+    }else{
+      if( d_tgt && d_n.getKind()==FORALL ){
+        //do nothing
+      }else{
+        //reset the first child to d_tgt
+        d_child_counter = 0;
+        getChild( d_child_counter )->reset( p, d_tgt, qi );
+      }
+    }
+  }
+  d_binding = false;
+  d_wasSet = true;
+  Debug("qcf-match") << "     reset: Finished reset for " << d_n << ", success = " << ( !d_qn.empty() || d_child_counter!=-1 ) << std::endl;
+}
+
+bool MatchGen::getNextMatch( QuantConflictFind * p, QuantInfo * qi ) {
+  Debug("qcf-match") << "     Get next match for : " << d_n << ", type = ";
+  debugPrintType( "qcf-match", d_type );
+  Debug("qcf-match") << ", children = " << d_children.size() << ", binding = " << d_binding << std::endl;
+  if( d_type==typ_invalid || d_type==typ_ground ){
+    if( d_child_counter==0 ){
+      d_child_counter = -1;
+      return true;
+    }else{
+      d_wasSet = false;
+      return false;
+    }
+  }else if( d_type==typ_var || d_type==typ_eq || d_type==typ_pred || d_type==typ_bool_var || d_type==typ_tconstraint || d_type==typ_tsym ){
+    bool success = false;
+    bool terminate = false;
+    do {
+      bool doReset = false;
+      bool doFail = false;
+      if( !d_binding ){
+        if( doMatching( p, qi ) ){
+          Debug("qcf-match-debug") << "     - Matching succeeded" << std::endl;
+          d_binding = true;
+          d_binding_it = d_qni_bound.begin();
+          doReset = true;
+          //for tconstraint, add constraint
+          if( d_type==typ_tconstraint ){
+            std::map< Node, bool >::iterator it = qi->d_tconstraints.find( d_n );
+            if( it==qi->d_tconstraints.end() ){
+              qi->d_tconstraints[d_n] = d_tgt;
+              //store that we added this constraint
+              d_qni_bound_cons[0] = d_n;
+            }else if( d_tgt!=it->second ){
+              success = false;
+              terminate = true;
+            }
+          }
+        }else{
+          Debug("qcf-match-debug") << "     - Matching failed" << std::endl;
+          success = false;
+          terminate = true;
+        }
+      }else{
+        doFail = true;
+      }
+      if( d_binding ){
+        //also need to create match for each variable we bound
+        success = true;
+        Debug("qcf-match-debug") << "     Produce matches for bound variables by " << d_n << ", type = ";
+        debugPrintType( "qcf-match-debug", d_type );
+        Debug("qcf-match-debug") << "..." << std::endl;
+
+        while( ( success && d_binding_it!=d_qni_bound.end() ) || doFail ){
+          std::map< int, MatchGen * >::iterator itm;
+          if( !doFail ){
+            Debug("qcf-match-debug") << "       check variable " << d_binding_it->second << std::endl;
+            itm = qi->d_var_mg.find( d_binding_it->second );
+          }
+          if( doFail || ( d_binding_it->first!=0 && itm!=qi->d_var_mg.end() ) ){
+            Debug("qcf-match-debug") << "       we had bound variable " << d_binding_it->second << ", reset = " << doReset << std::endl;
+            if( doReset ){
+              itm->second->reset( p, true, qi );
+            }
+            if( doFail || !itm->second->getNextMatch( p, qi ) ){
+              do {
+                if( d_binding_it==d_qni_bound.begin() ){
+                  Debug("qcf-match-debug") << "       failed." << std::endl;
+                  success = false;
+                }else{
+                  --d_binding_it;
+                  Debug("qcf-match-debug") << "       decrement..." << std::endl;
+                }
+              }while( success && ( d_binding_it->first==0 || qi->d_var_mg.find( d_binding_it->second )==qi->d_var_mg.end() ) );
+              doReset = false;
+              doFail = false;
+            }else{
+              Debug("qcf-match-debug") << "       increment..." << std::endl;
+              ++d_binding_it;
+              doReset = true;
+            }
+          }else{
+            Debug("qcf-match-debug") << "       skip..." << d_binding_it->second << std::endl;
+            ++d_binding_it;
+            doReset = true;
+          }
+        }
+        if( !success ){
+          d_binding = false;
+        }else{
+          terminate = true;
+          if( d_binding_it==d_qni_bound.begin() ){
+            d_binding = false;
+          }
+        }
+      }
+    }while( !terminate );
+    //if not successful, clean up the variables you bound
+    if( !success ){
+      if( d_type==typ_eq || d_type==typ_pred ){
+        //clean up the constraints you added
+        for( std::map< int, TNode >::iterator it = d_qni_bound_cons.begin(); it != d_qni_bound_cons.end(); ++it ){
+          if( !it->second.isNull() ){
+            Debug("qcf-match") << "       Clean up bound var " << it->first << (d_tgt ? "!" : "") << " = " << it->second << std::endl;
+            std::map< int, int >::iterator itb = d_qni_bound_cons_var.find( it->first );
+            int vn = itb!=d_qni_bound_cons_var.end() ? itb->second : -1;
+            //Trace("qcf-explain") << "       cleanup: " << d_n << " remove constraint " << it->first << " -> " << it->second << " (vn=" << vn << ")" << ", d_tgt = " << d_tgt << std::endl;
+            qi->addConstraint( p, it->first, it->second, vn, d_tgt, true );
+          }
+        }
+        d_qni_bound_cons.clear();
+        d_qni_bound_cons_var.clear();
+        d_qni_bound.clear();
+      }else{
+        //clean up the matches you set
+        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){
+          Debug("qcf-match") << "       Clean up bound var " << it->second << std::endl;
+          Assert( it->second<qi->getNumVars() );
+          qi->d_match[ it->second ] = TNode::null();
+          qi->d_match_term[ it->second ] = TNode::null();
+        }
+        d_qni_bound.clear();
+      }
+      if( d_type==typ_tconstraint ){
+        //remove constraint if applicable
+        if( d_qni_bound_cons.find( 0 )!=d_qni_bound_cons.end() ){
+          qi->d_tconstraints.erase( d_n );
+          d_qni_bound_cons.clear();
+        }
+      }
+      /*
+      if( d_type==typ_var && p->d_effort==QuantConflictFind::effort_mc && !d_matched_basis ){
+        d_matched_basis = true;
+        Node f = getOperator( d_n );
+        TNode mbo = p->getTermDatabase()->getModelBasisOpTerm( f );
+        if( qi->setMatch( p, d_qni_var_num[0], mbo ) ){
+          success = true;
+          d_qni_bound[0] = d_qni_var_num[0];
+        }
+      }
+      */
+    }
+    Debug("qcf-match") << "    ...finished matching for " << d_n << ", success = " << success << std::endl;
+    d_wasSet = success;
+    return success;
+  }else if( d_type==typ_formula || d_type==typ_ite_var ){
+    bool success = false;
+    if( d_child_counter<0 ){
+      if( d_child_counter<-1 ){
+        success = true;
+        d_child_counter = -1;
+      }
+    }else{
+      while( !success && d_child_counter>=0 ){
+        //transition system based on d_child_counter
+        if( d_n.getKind()==OR || d_n.getKind()==AND ){
+          if( (d_n.getKind()==AND)==d_tgt ){
+            //all children must match simultaneously
+            if( getChild( d_child_counter )->getNextMatch( p, qi ) ){
+              if( d_child_counter<(int)(getNumChildren()-1) ){
+                d_child_counter++;
+                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << std::endl;
+                getChild( d_child_counter )->reset( p, d_tgt, qi );
+              }else{
+                success = true;
+              }
+            }else{
+              //if( std::find( d_independent.begin(), d_independent.end(), d_child_counter )!=d_independent.end() ){
+              //  d_child_counter--;
+              //}else{
+              d_child_counter--;
+              //}
+            }
+          }else{
+            //one child must match
+            if( !getChild( d_child_counter )->getNextMatch( p, qi ) ){
+              if( d_child_counter<(int)(getNumChildren()-1) ){
+                d_child_counter++;
+                Debug("qcf-match-debug") << "       Reset child " << d_child_counter << " of " << d_n << ", one match" << std::endl;
+                getChild( d_child_counter )->reset( p, d_tgt, qi );
+              }else{
+                d_child_counter = -1;
+              }
+            }else{
+              success = true;
+            }
+          }
+        }else if( d_n.getKind()==IFF ){
+          //construct match based on both children
+          if( d_child_counter%2==0 ){
+            if( getChild( 0 )->getNextMatch( p, qi ) ){
+              d_child_counter++;
+              getChild( 1 )->reset( p, d_child_counter==1, qi );
+            }else{
+              if( d_child_counter==0 ){
+                d_child_counter = 2;
+                getChild( 0 )->reset( p, !d_tgt, qi );
+              }else{
+                d_child_counter = -1;
+              }
+            }
+          }
+          if( d_child_counter>=0 && d_child_counter%2==1 ){
+            if( getChild( 1 )->getNextMatch( p, qi ) ){
+              success = true;
+            }else{
+              d_child_counter--;
+            }
+          }
+        }else if( d_n.getKind()==ITE ){
+          if( d_child_counter%2==0 ){
+            int index1 = d_child_counter==4 ? 1 : 0;
+            if( getChild( index1 )->getNextMatch( p, qi ) ){
+              d_child_counter++;
+              getChild( d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2) )->reset( p, d_tgt, qi );
+            }else{
+              if( d_child_counter==4 || ( d_type==typ_ite_var && d_child_counter==2 ) ){
+                d_child_counter = -1;
+              }else{
+                d_child_counter +=2;
+                getChild( d_child_counter==2 ? 0 : 1 )->reset( p, d_child_counter==2 ? !d_tgt : d_tgt, qi );
+              }
+            }
+          }
+          if( d_child_counter>=0 && d_child_counter%2==1 ){
+            int index2 = d_child_counter==5 ? 2 : (d_tgt==(d_child_counter==1) ? 1 : 2);
+            if( getChild( index2 )->getNextMatch( p, qi ) ){
+              success = true;
+            }else{
+              d_child_counter--;
+            }
+          }
+        }else if( d_n.getKind()==FORALL ){
+          if( getChild( d_child_counter )->getNextMatch( p, qi ) ){
+            success = true;
+          }else{
+            d_child_counter = -1;
+          }
+        }
+      }
+        d_wasSet = success;
+      Debug("qcf-match") << "    ...finished construct match for " << d_n << ", success = " << success << std::endl;
+      return success;
+    }
+  }
+  Debug("qcf-match") << "    ...already finished for " << d_n << std::endl;
+  return false;
+}
+
+bool MatchGen::getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp ) {
+  if( d_type==typ_eq ){
+    Node n[2];
+    for( unsigned i=0; i<2; i++ ){
+      Trace("qcf-explain") << "Explain term " << d_n[i] << "..." << std::endl;
+      n[i] = getExplanationTerm( p, qi, d_n[i], exp );
+    }
+    Node eq = n[0].eqNode( n[1] );
+    if( !d_tgt_orig ){
+      eq = eq.negate();
+    }
+    exp.push_back( eq );
+    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << eq << ", set = " << d_wasSet << std::endl;
+    return true;
+  }else if( d_type==typ_pred ){
+    Trace("qcf-explain") << "Explain term " << d_n << "..." << std::endl;
+    Node n = getExplanationTerm( p, qi, d_n, exp );
+    if( !d_tgt_orig ){
+      n = n.negate();
+    }
+    exp.push_back( n );
+    Trace("qcf-explain") << "Explanation for " << d_n << " (tgt=" << d_tgt_orig << ") is " << n << ", set = " << d_wasSet << std::endl;
+    return true;
+  }else if( d_type==typ_formula ){
+    Trace("qcf-explain") << "Explanation get for " << d_n << ", counter = " << d_child_counter << ", tgt = " << d_tgt_orig << ", set = " << d_wasSet << std::endl;
+    if( d_n.getKind()==OR || d_n.getKind()==AND ){
+      if( (d_n.getKind()==AND)==d_tgt ){
+        for( unsigned i=0; i<getNumChildren(); i++ ){
+          if( !getChild( i )->getExplanation( p, qi, exp ) ){
+            return false;
+          }
+        }
+      }else{
+        return getChild( d_child_counter )->getExplanation( p, qi, exp );
+      }
+    }else if( d_n.getKind()==IFF ){
+      for( unsigned i=0; i<2; i++ ){
+        if( !getChild( i )->getExplanation( p, qi, exp ) ){
+          return false;
+        }
+      }
+    }else if( d_n.getKind()==ITE ){
+      for( unsigned i=0; i<3; i++ ){
+        bool isActive = ( ( i==0 && d_child_counter!=5 ) ||
+                          ( i==1 && d_child_counter!=( d_tgt ? 3 : 1 ) ) ||
+                          ( i==2 && d_child_counter!=( d_tgt ? 1 : 3 ) ) );
+        if( isActive ){
+          if( !getChild( i )->getExplanation( p, qi, exp ) ){
+            return false;
+          }
+        }
+      }
+    }else{
+      return false;
+    }
+    return true;
+  }else{
+    return false;
+  }
+}
+
+Node MatchGen::getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp ) {
+  Node v = qi->getCurrentExpValue( t );
+  if( isHandledUfTerm( t ) ){
+    for( unsigned i=0; i<t.getNumChildren(); i++ ){
+      Node vi = getExplanationTerm( p, qi, t[i], exp );
+      if( vi!=v[i] ){
+        Node eq = vi.eqNode( v[i] );
+        if( std::find( exp.begin(), exp.end(), eq )==exp.end() ){
+          Trace("qcf-explain") << "  add : " << eq << "." << std::endl;
+          exp.push_back( eq );
+        }
+      }
+    }
+  }
+  return v;
+}
+
+bool MatchGen::doMatching( QuantConflictFind * p, QuantInfo * qi ) {
+  if( !d_qn.empty() ){
+    if( d_qn[0]==NULL ){
+      d_qn.clear();
+      return true;
+    }else{
+      Assert( d_type==typ_var );
+      Assert( d_qni_size>0 );
+      bool invalidMatch;
+      do {
+        invalidMatch = false;
+        Debug("qcf-match-debug") << "       Do matching " << d_n << " " << d_qn.size() << " " << d_qni.size() << std::endl;
+        if( d_qn.size()==d_qni.size()+1 ) {
+          int index = (int)d_qni.size();
+          //initialize
+          TNode val;
+          std::map< int, int >::iterator itv = d_qni_var_num.find( index );
+          if( itv!=d_qni_var_num.end() ){
+            //get the representative variable this variable is equal to
+            int repVar = qi->getCurrentRepVar( itv->second );
+            Debug("qcf-match-debug") << "       Match " << index << " is a variable " << itv->second << ", which is repVar " << repVar << std::endl;
+            //get the value the rep variable
+            //std::map< int, TNode >::iterator itm = qi->d_match.find( repVar );
+            if( !qi->d_match[repVar].isNull() ){
+              val = qi->d_match[repVar];
+              Debug("qcf-match-debug") << "       Variable is already bound to " << val << std::endl;
+            }else{
+              //binding a variable
+              d_qni_bound[index] = repVar;
+              std::map< TNode, TermArgTrie >::iterator it = d_qn[index]->d_data.begin();
+              if( it != d_qn[index]->d_data.end() ) {
+                d_qni.push_back( it );
+                //set the match
+                if( it->first.getType().isSubtypeOf( qi->d_var_types[repVar] ) && qi->setMatch( p, d_qni_bound[index], it->first ) ){
+                  Debug("qcf-match-debug") << "       Binding variable" << std::endl;
+                  if( d_qn.size()<d_qni_size ){
+                    d_qn.push_back( &it->second );
+                  }
+                }else{
+                  Debug("qcf-match") << "       Binding variable, currently fail." << std::endl;
+                  invalidMatch = true;
+                }
+              }else{
+                Debug("qcf-match-debug") << "       Binding variable, fail, no more variables to bind" << std::endl;
+                d_qn.pop_back();
+              }
+            }
+          }else{
+            Debug("qcf-match-debug") << "       Match " << index << " is ground term" << std::endl;
+            Assert( d_qni_gterm.find( index )!=d_qni_gterm.end() );
+            Assert( d_qni_gterm_rep.find( index )!=d_qni_gterm_rep.end() );
+            val = d_qni_gterm_rep[index];
+            Assert( !val.isNull() );
+          }
+          if( !val.isNull() ){
+            //constrained by val
+            std::map< TNode, TermArgTrie >::iterator it = d_qn[index]->d_data.find( val );
+            if( it!=d_qn[index]->d_data.end() ){
+              Debug("qcf-match-debug") << "       Match" << std::endl;
+              d_qni.push_back( it );
+              if( d_qn.size()<d_qni_size ){
+                d_qn.push_back( &it->second );
+              }
+            }else{
+              Debug("qcf-match-debug") << "       Failed to match" << std::endl;
+              d_qn.pop_back();
+            }
+          }
+        }else{
+          Assert( d_qn.size()==d_qni.size() );
+          int index = d_qni.size()-1;
+          //increment if binding this variable
+          bool success = false;
+          std::map< int, int >::iterator itb = d_qni_bound.find( index );
+          if( itb!=d_qni_bound.end() ){
+            d_qni[index]++;
+            if( d_qni[index]!=d_qn[index]->d_data.end() ){
+              success = true;
+              if( qi->setMatch( p, itb->second, d_qni[index]->first ) ){
+                Debug("qcf-match-debug") << "       Bind next variable" << std::endl;
+                if( d_qn.size()<d_qni_size ){
+                  d_qn.push_back( &d_qni[index]->second );
+                }
+              }else{
+                Debug("qcf-match-debug") << "       Bind next variable, currently fail" << std::endl;
+                invalidMatch = true;
+              }
+            }else{
+              qi->d_match[ itb->second ] = TNode::null();
+              qi->d_match_term[ itb->second ] = TNode::null();
+              Debug("qcf-match-debug") << "       Bind next variable, no more variables to bind" << std::endl;
+            }
+          }else{
+            //TODO : if it equal to something else, also try that
+          }
+          //if not incrementing, move to next
+          if( !success ){
+            d_qn.pop_back();
+            d_qni.pop_back();
+          }
+        }
+      }while( ( !d_qn.empty() && d_qni.size()!=d_qni_size ) || invalidMatch );
+      if( d_qni.size()==d_qni_size ){
+        //Assert( !d_qni[d_qni.size()-1]->second.d_data.empty() );
+        //Debug("qcf-match-debug") << "       We matched " << d_qni[d_qni.size()-1]->second.d_children.begin()->first << std::endl;
+        Assert( !d_qni[d_qni.size()-1]->second.d_data.empty() );
+        TNode t = d_qni[d_qni.size()-1]->second.d_data.begin()->first;
+        Debug("qcf-match-debug") << "       " << d_n << " matched " << t << std::endl;
+        qi->d_match_term[d_qni_var_num[0]] = t;
+        //set the match terms
+        for( std::map< int, int >::iterator it = d_qni_bound.begin(); it != d_qni_bound.end(); ++it ){
+          Debug("qcf-match-debug") << "       position " << it->first << " bounded " << it->second << " / " << qi->d_q[0].getNumChildren() << std::endl;
+          //if( it->second<(int)qi->d_q[0].getNumChildren() ){   //if it is an actual variable, we are interested in knowing the actual term
+          if( it->first>0 ){
+            Assert( !qi->d_match[ it->second ].isNull() );
+            Assert( p->areEqual( t[it->first-1], qi->d_match[ it->second ] ) );
+            qi->d_match_term[it->second] = t[it->first-1];
+          }
+          //}
+        }
+      }
+    }
+  }
+  return !d_qn.empty();
+}
+
+void MatchGen::debugPrintType( const char * c, short typ, bool isTrace ) {
+  if( isTrace ){
+    switch( typ ){
+    case typ_invalid: Trace(c) << "invalid";break;
+    case typ_ground: Trace(c) << "ground";break;
+    case typ_eq: Trace(c) << "eq";break;
+    case typ_pred: Trace(c) << "pred";break;
+    case typ_formula: Trace(c) << "formula";break;
+    case typ_var: Trace(c) << "var";break;
+    case typ_ite_var: Trace(c) << "ite_var";break;
+    case typ_bool_var: Trace(c) << "bool_var";break;
+    }
+  }else{
+    switch( typ ){
+    case typ_invalid: Debug(c) << "invalid";break;
+    case typ_ground: Debug(c) << "ground";break;
+    case typ_eq: Debug(c) << "eq";break;
+    case typ_pred: Debug(c) << "pred";break;
+    case typ_formula: Debug(c) << "formula";break;
+    case typ_var: Debug(c) << "var";break;
+    case typ_ite_var: Debug(c) << "ite_var";break;
+    case typ_bool_var: Debug(c) << "bool_var";break;
+    }
+  }
+}
+
+void MatchGen::setInvalid() {
+  d_type = typ_invalid;
+  d_children.clear();
+}
+
+bool MatchGen::isHandledBoolConnective( TNode n ) {
+  return n.getType().isBoolean() && ( n.getKind()==OR || n.getKind()==AND || n.getKind()==IFF || n.getKind()==ITE || n.getKind()==FORALL || n.getKind()==NOT );
+}
+
+bool MatchGen::isHandledUfTerm( TNode n ) {
+  //return n.getKind()==APPLY_UF || n.getKind()==STORE || n.getKind()==SELECT ||
+  //       n.getKind()==APPLY_CONSTRUCTOR || n.getKind()==APPLY_SELECTOR_TOTAL || n.getKind()==APPLY_TESTER;
+  return inst::Trigger::isAtomicTriggerKind( n.getKind() );
+}
+
+Node MatchGen::getOperator( QuantConflictFind * p, Node n ) {
+  if( isHandledUfTerm( n ) ){
+    return p->getTermDatabase()->getOperator( n );
+  }else{
+    return Node::null();
+  }
+}
+
+bool MatchGen::isHandled( TNode n ) {
+  if( n.getKind()!=BOUND_VARIABLE && n.hasBoundVar() ){
+    if( !isHandledBoolConnective( n ) && !isHandledUfTerm( n ) && n.getKind()!=EQUAL && n.getKind()!=ITE ){
+      return false;
+    }
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      if( !isHandled( n[i] ) ){
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+
+QuantConflictFind::QuantConflictFind( QuantifiersEngine * qe, context::Context* c ) :
+QuantifiersModule( qe ),
+d_conflict( c, false ),
+d_qassert( c ) {
+  d_fid_count = 0;
+  d_true = NodeManager::currentNM()->mkConst<bool>(true);
+  d_false = NodeManager::currentNM()->mkConst<bool>(false);
+}
+
+Node QuantConflictFind::mkEqNode( Node a, Node b ) {
+  if( a.getType().isBoolean() ){
+    return a.iffNode( b );
+  }else{
+    return a.eqNode( b );
+  }
+}
+
+//-------------------------------------------------- registration
+
+void QuantConflictFind::registerQuantifier( Node q ) {
+  if( d_quantEngine->hasOwnership( q, this ) ){
+    d_quants.push_back( q );
+    d_quant_id[q] = d_quants.size();
+    Trace("qcf-qregister") << "Register ";
+    debugPrintQuant( "qcf-qregister", q );
+    Trace("qcf-qregister") << " : " << q << std::endl;
+    //make QcfNode structure
+    Trace("qcf-qregister") << "- Get relevant equality/disequality pairs, calculate flattening..." << std::endl;
+    d_qinfo[q].initialize( q, q[1] );
+
+    //debug print
+    Trace("qcf-qregister") << "- Flattened structure is :" << std::endl;
+    Trace("qcf-qregister") << "    ";
+    debugPrintQuantBody( "qcf-qregister", q, q[1] );
+    Trace("qcf-qregister") << std::endl;
+    if( d_qinfo[q].d_vars.size()>q[0].getNumChildren() ){
+      Trace("qcf-qregister") << "  with additional constraints : " << std::endl;
+      for( unsigned j=q[0].getNumChildren(); j<d_qinfo[q].d_vars.size(); j++ ){
+        Trace("qcf-qregister") << "    ?x" << j << " = ";
+        debugPrintQuantBody( "qcf-qregister", q, d_qinfo[q].d_vars[j], false );
+        Trace("qcf-qregister") << std::endl;
+      }
+    }
+
+    Trace("qcf-qregister") << "Done registering quantifier." << std::endl;
+  }
+}
+
+int QuantConflictFind::evaluate( Node n, bool pref, bool hasPref ) {
+  int ret = 0;
+  if( n.getKind()==EQUAL ){
+    Node n1 = evaluateTerm( n[0] );
+    Node n2 = evaluateTerm( n[1] );
+    Debug("qcf-eval") << "Evaluate : Normalize " << n << " to " << n1 << " = " << n2 << std::endl;
+    if( areEqual( n1, n2 ) ){
+      ret = 1;
+    }else if( areDisequal( n1, n2 ) ){
+      ret = -1;
+    }
+    //else if( d_effort>QuantConflictFind::effort_conflict ){
+    //  ret = -1;
+    //}
+  }else if( MatchGen::isHandledUfTerm( n ) ){  //predicate
+    Node nn = evaluateTerm( n );
+    Debug("qcf-eval") << "Evaluate : Normalize " << nn << " to " << n << std::endl;
+    if( areEqual( nn, d_true ) ){
+      ret = 1;
+    }else if( areEqual( nn, d_false ) ){
+      ret = -1;
+    }
+    //else if( d_effort>QuantConflictFind::effort_conflict ){
+    //  ret = -1;
+    //}
+  }else if( n.getKind()==NOT ){
+    return -evaluate( n[0] );
+  }else if( n.getKind()==ITE ){
+    int cev1 = evaluate( n[0] );
+    int cevc[2] = { 0, 0 };
+    for( unsigned i=0; i<2; i++ ){
+      if( ( i==0 && cev1!=-1 ) || ( i==1 && cev1!=1 ) ){
+        cevc[i] = evaluate( n[i+1] );
+        if( cev1!=0 ){
+          ret = cevc[i];
+          break;
+        }else if( cevc[i]==0 ){
+          break;
+        }
+      }
+    }
+    if( ret==0 && cevc[0]!=0 && cevc[0]==cevc[1] ){
+      ret = cevc[0];
+    }
+  }else if( n.getKind()==IFF ){
+    int cev1 = evaluate( n[0] );
+    if( cev1!=0 ){
+      int cev2 = evaluate( n[1] );
+      if( cev2!=0 ){
+        ret = cev1==cev2 ? 1 : -1;
+      }
+    }
+
+  }else{
+    int ssval = 0;
+    if( n.getKind()==OR ){
+      ssval = 1;
+    }else if( n.getKind()==AND ){
+      ssval = -1;
+    }
+    bool isUnk = false;
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      int cev = evaluate( n[i] );
+      if( cev==ssval ){
+        ret = ssval;
+        break;
+      }else if( cev==0 ){
+        isUnk = true;
+      }
+    }
+    if( ret==0 && !isUnk ){
+      ret = -ssval;
+    }
+  }
+  Debug("qcf-eval") << "Evaluate " << n << " to " << ret << std::endl;
+  return ret;
+}
+
+short QuantConflictFind::getMaxQcfEffort() {
+  if( options::qcfMode()==QCF_CONFLICT_ONLY ){
+    return effort_conflict;
+  }else if( options::qcfMode()==QCF_PROP_EQ ){
+    return effort_prop_eq;
+  }else if( options::qcfMode()==QCF_MC ){
+    return effort_mc;
+  }else{
+    return 0;
+  }
+}
+
+bool QuantConflictFind::areMatchEqual( TNode n1, TNode n2 ) {
+  //if( d_effort==QuantConflictFind::effort_mc ){
+  //  return n1==n2 || !areDisequal( n1, n2 );
+  //}else{
+  return n1==n2;
+  //}
+}
+
+bool QuantConflictFind::areMatchDisequal( TNode n1, TNode n2 ) {
+  //if( d_effort==QuantConflictFind::effort_conflict ){
+  //  return areDisequal( n1, n2 );
+  //}else{
+  return n1!=n2;
+  //}
+}
+
+//-------------------------------------------------- handling assertions / eqc
+
+void QuantConflictFind::assertNode( Node q ) {
+  if( d_quantEngine->hasOwnership( q, this ) ){
+    Trace("qcf-proc") << "QCF : assertQuantifier : ";
+    debugPrintQuant("qcf-proc", q);
+    Trace("qcf-proc") << std::endl;
+    d_qassert.push_back( q );
+    //set the eqRegistries that this depends on to true
+    //for( std::map< EqRegistry *, bool >::iterator it = d_qinfo[q].d_rel_eqr.begin(); it != d_qinfo[q].d_rel_eqr.end(); ++it ){
+    //  it->first->d_active.set( true );
+    //}
+  }
+}
+
+Node QuantConflictFind::evaluateTerm( Node n ) {
+  if( MatchGen::isHandledUfTerm( n ) ){
+    Node f = MatchGen::getOperator( this, n );
+    Node nn;
+    if( getEqualityEngine()->hasTerm( n ) ){
+      nn = getTermDatabase()->existsTerm( f, n );
+    }else{
+      std::vector< TNode > args;
+      for( unsigned i=0; i<n.getNumChildren(); i++ ){
+        Node c = evaluateTerm( n[i] );
+        args.push_back( c );
+      }
+      nn = getTermDatabase()->d_func_map_trie[f].existsTerm( args );
+    }
+    if( !nn.isNull() ){
+      Debug("qcf-eval") << "GT: Term " << nn << " for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;
+      return getRepresentative( nn );
+    }else{
+      Debug("qcf-eval") << "GT: No term for " << n << " hasTerm = " << getEqualityEngine()->hasTerm( n )  << std::endl;
+      return n;
+    }
+  }else if( n.getKind()==ITE ){
+    int v = evaluate( n[0], false, false );
+    if( v==1 ){
+      return evaluateTerm( n[1] );
+    }else if( v==-1 ){
+      return evaluateTerm( n[2] );
+    }
+  }
+  return getRepresentative( n );
+}
+
+/** new node */
+void QuantConflictFind::newEqClass( Node n ) {
+
+}
+
+/** merge */
+void QuantConflictFind::merge( Node a, Node b ) {
+
+}
+
+/** assert disequal */
+void QuantConflictFind::assertDisequal( Node a, Node b ) {
+
+}
+
+//-------------------------------------------------- check function
+
+bool QuantConflictFind::needsCheck( Theory::Effort level ) {
+  bool performCheck = false;
+  if( options::quantConflictFind() && !d_conflict ){
+    if( level==Theory::EFFORT_LAST_CALL ){
+      performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_LAST_CALL;
+    }else if( level==Theory::EFFORT_FULL ){
+      performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_DEFAULT;
+    }else if( level==Theory::EFFORT_STANDARD ){
+      performCheck = options::qcfWhenMode()==QCF_WHEN_MODE_STD;
+    }
+  }
+  return performCheck;
+}
+
+void QuantConflictFind::reset_round( Theory::Effort level ) {
+  d_needs_computeRelEqr = true;
+}
+
+/** check */
+void QuantConflictFind::check( Theory::Effort level, unsigned quant_e ) {
+  if( quant_e==QuantifiersEngine::QEFFORT_CONFLICT ){
+    Trace("qcf-check") << "QCF : check : " << level << std::endl;
+    if( d_conflict ){
+      Trace("qcf-check2") << "QCF : finished check : already in conflict." << std::endl;
+      if( level>=Theory::EFFORT_FULL ){
+        Trace("qcf-warn") << "ALREADY IN CONFLICT? " << level << std::endl;
+        //Assert( false );
+      }
+    }else{
+      int addedLemmas = 0;
+      ++(d_statistics.d_inst_rounds);
+      double clSet = 0;
+      int prevEt = 0;
+      if( Trace.isOn("qcf-engine") ){
+        prevEt = d_statistics.d_entailment_checks.getData();
+        clSet = double(clock())/double(CLOCKS_PER_SEC);
+        Trace("qcf-engine") << "---Conflict Find Engine Round, effort = " << level << "---" << std::endl;
+      }
+      computeRelevantEqr();
+
+      //determine order for quantified formulas
+      std::vector< Node > qorder;
+      std::map< Node, bool > qassert;
+      //mark which are asserted
+      for( unsigned i=0; i<d_qassert.size(); i++ ){
+        qassert[d_qassert[i]] = true;
+      }
+      //add which ones are specified in the order
+      for( unsigned i=0; i<d_quant_order.size(); i++ ){
+        Node n = d_quant_order[i];
+        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() && qassert.find( n )!=qassert.end() ){
+          qorder.push_back( n );
+        }
+      }
+      d_quant_order.clear();
+      d_quant_order.insert( d_quant_order.begin(), qorder.begin(), qorder.end() );
+      //add remaining
+      for( unsigned i=0; i<d_qassert.size(); i++ ){
+        Node n = d_qassert[i];
+        if( std::find( qorder.begin(), qorder.end(), n )==qorder.end() ){
+          qorder.push_back( n );
+        }
+      }
+
+      if( Trace.isOn("qcf-debug") ){
+        Trace("qcf-debug") << std::endl;
+        debugPrint("qcf-debug");
+        Trace("qcf-debug") << std::endl;
+      }
+      short end_e = getMaxQcfEffort();
+      for( short e = effort_conflict; e<=end_e; e++ ){
+        d_effort = e;
+        Trace("qcf-check") << "Checking quantified formulas at effort " << e << "..." << std::endl;
+        for( unsigned j=0; j<qorder.size(); j++ ){
+          Node q = qorder[j];
+          QuantInfo * qi = &d_qinfo[q];
+
+          Assert( d_qinfo.find( q )!=d_qinfo.end() );
+          if( qi->d_mg->isValid() ){
+            Trace("qcf-check") << "Check quantified formula ";
+            debugPrintQuant("qcf-check", q);
+            Trace("qcf-check") << " : " << q << "..." << std::endl;
+
+            Trace("qcf-check-debug") << "Reset round..." << std::endl;
+            qi->reset_round( this );
+            //try to make a matches making the body false
+            Trace("qcf-check-debug") << "Get next match..." << std::endl;
+            while( qi->d_mg->getNextMatch( this, qi ) ){
+              Trace("qcf-inst") << "*** Produced match at effort " << e << " : " << std::endl;
+              qi->debugPrintMatch("qcf-inst");
+              Trace("qcf-inst") << std::endl;
+              std::vector< int > assigned;
+              if( !qi->isMatchSpurious( this ) ){
+                if( qi->completeMatch( this, assigned ) ){
+                  std::vector< Node > terms;
+                  qi->getMatch( terms );
+                  if( !qi->isTConstraintSpurious( this, terms ) ){
+                    if( Debug.isOn("qcf-check-inst") ){
+                      //if( e==effort_conflict ){
+                      Node inst = d_quantEngine->getInstantiation( q, terms );
+                      Debug("qcf-check-inst") << "Check instantiation " << inst << "..." << std::endl;
+                      Assert( evaluate( inst )!=1 );
+                      Assert( evaluate( inst )==-1 || e>effort_conflict );
+                      //}
+                    }
+                    if( d_quantEngine->addInstantiation( q, terms, false ) ){
+                      Trace("qcf-check") << "   ... Added instantiation" << std::endl;
+                      Trace("qcf-inst") << "*** Was from effort " << e << " : " << std::endl;
+                      qi->debugPrintMatch("qcf-inst");
+                      Trace("qcf-inst") << std::endl;
+                      ++addedLemmas;
+                      if( e==effort_conflict ){
+                        d_quant_order.insert( d_quant_order.begin(), q );
+                        d_conflict.set( true );
+                        ++(d_statistics.d_conflict_inst);
+                        break;
+                      }else if( e==effort_prop_eq ){
+                        ++(d_statistics.d_prop_inst);
+                      }
+                    }else{
+                      Trace("qcf-inst") << "   ... Failed to add instantiation" << std::endl;
+                      //Assert( false );
+                    }
+                  }
+                  //clean up assigned
+                  qi->revertMatch( assigned );
+                  d_tempCache.clear();
+                }else{
+                  Trace("qcf-inst") << "   ... Spurious instantiation (cannot assign unassigned variables)" << std::endl;
+                }
+              }else{
+                Trace("qcf-inst") << "   ... Spurious instantiation (match is inconsistent)" << std::endl;
+              }
+            }
+            if( d_conflict ){
+              break;
+            }
+          }
+        }
+        if( addedLemmas>0 ){
+          break;
+        }
+      }
+      if( Trace.isOn("qcf-engine") ){
+        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
+        Trace("qcf-engine") << "Finished conflict find engine, time = " << (clSet2-clSet);
+        if( addedLemmas>0 ){
+          Trace("qcf-engine") << ", effort = " << ( d_effort==effort_conflict ? "conflict" : ( d_effort==effort_prop_eq ? "prop_eq" : "mc" ) );
+          Trace("qcf-engine") << ", addedLemmas = " << addedLemmas;
+        }
+        Trace("qcf-engine") << std::endl;
+        int currEt = d_statistics.d_entailment_checks.getData();
+        if( currEt!=prevEt ){
+          Trace("qcf-engine") << "  Entailment checks = " << ( currEt - prevEt ) << std::endl;
+        }
+      }
+      Trace("qcf-check2") << "QCF : finished check : " << level << std::endl;
+    }
+  }
+}
+
+void QuantConflictFind::computeRelevantEqr() {
+  if( d_needs_computeRelEqr ){
+    d_needs_computeRelEqr = false;
+    Trace("qcf-check") << "Compute relevant equalities..." << std::endl;
+    //d_uf_terms.clear();
+    //d_eqc_uf_terms.clear();
+    d_eqcs.clear();
+    d_model_basis.clear();
+    //d_arg_reps.clear();
+    //double clSet = 0;
+    //if( Trace.isOn("qcf-opt") ){
+    //  clSet = double(clock())/double(CLOCKS_PER_SEC);
+    //}
+
+    //long nTermst = 0;
+    //long nTerms = 0;
+    //long nEqc = 0;
+
+    //which nodes are irrelevant for disequality matches
+    std::map< TNode, bool > irrelevant_dnode;
+    //now, store matches
+    eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );
+    while( !eqcs_i.isFinished() ){
+      //nEqc++;
+      Node r = (*eqcs_i);
+      if( getTermDatabase()->hasTermCurrent( r ) ){
+        TypeNode rtn = r.getType();
+        if( options::qcfMode()==QCF_MC ){
+          std::map< TypeNode, std::vector< TNode > >::iterator itt = d_eqcs.find( rtn );
+          if( itt==d_eqcs.end() ){
+            Node mb = getTermDatabase()->getModelBasisTerm( rtn );
+            if( !getEqualityEngine()->hasTerm( mb ) ){
+              Trace("qcf-warn") << "WARNING: Model basis term does not exist!" << std::endl;
+              Assert( false );
+            }
+            Node mbr = getRepresentative( mb );
+            if( mbr!=r ){
+              d_eqcs[rtn].push_back( mbr );
+            }
+            d_eqcs[rtn].push_back( r );
+            d_model_basis[rtn] = mb;
+          }else{
+            itt->second.push_back( r );
+          }
+        }else{
+          d_eqcs[rtn].push_back( r );
+        }
+      }
+      ++eqcs_i;
+    }
+    /*
+    if( Trace.isOn("qcf-opt") ){
+      double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
+      Trace("qcf-opt") << "Compute rel eqc : " << std::endl;
+      Trace("qcf-opt") << "   " << nEqc << " equivalence classes. " << std::endl;
+      Trace("qcf-opt") << "   " << nTerms << " / " << nTermst << " terms." << std::endl;
+      Trace("qcf-opt") << "   Time : " << (clSet2-clSet) << std::endl;
+    }
+    */
+  }
+}
+
+
+//-------------------------------------------------- debugging
+
+
+void QuantConflictFind::debugPrint( const char * c ) {
+  //print the equivalance classes
+  Trace(c) << "----------EQ classes" << std::endl;
+  eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( getEqualityEngine() );
+  while( !eqcs_i.isFinished() ){
+    Node n = (*eqcs_i);
+    //if( !n.getType().isInteger() ){
+    Trace(c) << "  - " << n << " : {";
+    eq::EqClassIterator eqc_i = eq::EqClassIterator( n, getEqualityEngine() );
+    bool pr = false;
+    while( !eqc_i.isFinished() ){
+      Node nn = (*eqc_i);
+      if( nn.getKind()!=EQUAL && nn!=n ){
+        Trace(c) << (pr ? "," : "" ) << " " << nn;
+        pr = true;
+      }
+      ++eqc_i;
+    }
+    Trace(c) << (pr ? " " : "" ) << "}" << std::endl;
+    /*
+    EqcInfo * eqcn = getEqcInfo( n, false );
+    if( eqcn ){
+      Trace(c) << "    DEQ : {";
+      pr = false;
+      for( NodeBoolMap::iterator it = eqcn->d_diseq.begin(); it != eqcn->d_diseq.end(); ++it ){
+        if( (*it).second ){
+          Trace(c) << (pr ? "," : "" ) << " " << (*it).first;
+          pr = true;
+        }
+      }
+      Trace(c) << (pr ? " " : "" ) << "}" << std::endl;
+    }
+    //}
+    */
+    ++eqcs_i;
+  }
+}
+
+void QuantConflictFind::debugPrintQuant( const char * c, Node q ) {
+  Trace(c) << "Q" << d_quant_id[q];
+}
+
+void QuantConflictFind::debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum ) {
+  if( n.getNumChildren()==0 ){
+    Trace(c) << n;
+  }else if( doVarNum && d_qinfo[q].d_var_num.find( n )!=d_qinfo[q].d_var_num.end() ){
+    Trace(c) << "?x" << d_qinfo[q].d_var_num[n];
+  }else{
+    Trace(c) << "(";
+    if( n.getKind()==APPLY_UF ){
+      Trace(c) << n.getOperator();
+    }else{
+      Trace(c) << n.getKind();
+    }
+    for( unsigned i=0; i<n.getNumChildren(); i++ ){
+      Trace(c) << " ";
+      debugPrintQuantBody( c, q, n[i] );
+    }
+    Trace(c) << ")";
+  }
+}
+
+QuantConflictFind::Statistics::Statistics():
+  d_inst_rounds("QuantConflictFind::Inst_Rounds", 0),
+  d_conflict_inst("QuantConflictFind::Instantiations_Conflict_Find", 0 ),
+  d_prop_inst("QuantConflictFind::Instantiations_Prop", 0 ),
+  d_entailment_checks("QuantConflictFind::Entailment_Checks",0)
+{
+  StatisticsRegistry::registerStat(&d_inst_rounds);
+  StatisticsRegistry::registerStat(&d_conflict_inst);
+  StatisticsRegistry::registerStat(&d_prop_inst);
+  StatisticsRegistry::registerStat(&d_entailment_checks);
+}
+
+QuantConflictFind::Statistics::~Statistics(){
+  StatisticsRegistry::unregisterStat(&d_inst_rounds);
+  StatisticsRegistry::unregisterStat(&d_conflict_inst);
+  StatisticsRegistry::unregisterStat(&d_prop_inst);
+  StatisticsRegistry::unregisterStat(&d_entailment_checks);
+}
+
+TNode QuantConflictFind::getZero( Kind k ) {
+  std::map< Kind, Node >::iterator it = d_zero.find( k );
+  if( it==d_zero.end() ){
+    Node nn;
+    if( k==PLUS ){
+      nn = NodeManager::currentNM()->mkConst( Rational(0) );
+    }
+    d_zero[k] = nn;
+    return nn;
+  }else{
+    return it->second;
+  }
+}
+
+
+}
index 829b67777544212af78c3c88732154f18dd1fe55..d2a9827817a9d48bc66afb9df1a4c7a96986c3e9 100644 (file)
-/*********************                                                        */\r
-/*! \file quant_conflict_find.h\r
- ** \verbatim\r
- ** Original author: Andrew Reynolds\r
- ** Major contributors: none\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 project.\r
- ** Copyright (c) 2009-2014  New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief quantifiers conflict find class\r
- **/\r
-\r
-#include "cvc4_private.h"\r
-\r
-#ifndef QUANT_CONFLICT_FIND\r
-#define QUANT_CONFLICT_FIND\r
-\r
-#include "context/cdhashmap.h"\r
-#include "context/cdchunk_list.h"\r
-#include "theory/quantifiers_engine.h"\r
-#include "theory/quantifiers/term_database.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace quantifiers {\r
-\r
-class QuantConflictFind;\r
-class QuantInfo;\r
-\r
-//match generator\r
-class MatchGen {\r
-  friend class QuantInfo;\r
-private:\r
-  //current children information\r
-  int d_child_counter;\r
-  //children of this object\r
-  std::vector< int > d_children_order;\r
-  unsigned getNumChildren() { return d_children.size(); }\r
-  MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; }\r
-  //MatchGen * getChild( int i ) { return &d_children[i]; }\r
-  //current matching information\r
-  std::vector< TermArgTrie * > d_qn;\r
-  std::vector< std::map< TNode, TermArgTrie >::iterator > d_qni;\r
-  bool doMatching( QuantConflictFind * p, QuantInfo * qi );\r
-  //for matching : each index is either a variable or a ground term\r
-  unsigned d_qni_size;\r
-  std::map< int, int > d_qni_var_num;\r
-  std::map< int, TNode > d_qni_gterm;\r
-  std::map< int, TNode > d_qni_gterm_rep;\r
-  std::map< int, int > d_qni_bound;\r
-  std::vector< int > d_qni_bound_except;\r
-  std::map< int, TNode > d_qni_bound_cons;\r
-  std::map< int, int > d_qni_bound_cons_var;\r
-  std::map< int, int >::iterator d_binding_it;\r
-  //std::vector< int > d_independent;\r
-  bool d_matched_basis;\r
-  bool d_binding;\r
-  //int getVarBindingVar();\r
-  std::map< int, Node > d_ground_eval;\r
-  //determine variable order\r
-  void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars );\r
-  void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars );\r
-public:\r
-  //type of the match generator\r
-  enum {\r
-    typ_invalid,\r
-    typ_ground,\r
-    typ_pred,\r
-    typ_eq,\r
-    typ_formula,\r
-    typ_var,\r
-    typ_ite_var,\r
-    typ_bool_var,\r
-    typ_tconstraint,\r
-    typ_tsym,\r
-  };\r
-  void debugPrintType( const char * c, short typ, bool isTrace = false );\r
-public:\r
-  MatchGen() : d_type( typ_invalid ){}\r
-  MatchGen( QuantInfo * qi, Node n, bool isVar = false );\r
-  bool d_tgt;\r
-  bool d_tgt_orig;\r
-  bool d_wasSet;\r
-  Node d_n;\r
-  std::vector< MatchGen > d_children;\r
-  short d_type;\r
-  bool d_type_not;\r
-  void reset_round( QuantConflictFind * p );\r
-  void reset( QuantConflictFind * p, bool tgt, QuantInfo * qi );\r
-  bool getNextMatch( QuantConflictFind * p, QuantInfo * qi );\r
-  bool getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp );\r
-  Node getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp );\r
-  bool isValid() { return d_type!=typ_invalid; }\r
-  void setInvalid();\r
-\r
-  // is this term treated as UF application?\r
-  static bool isHandledBoolConnective( TNode n );\r
-  static bool isHandledUfTerm( TNode n );\r
-  static Node getOperator( QuantConflictFind * p, Node n );\r
-  //can this node be handled by the algorithm\r
-  static bool isHandled( TNode n );\r
-};\r
-\r
-//info for quantifiers\r
-class QuantInfo {\r
-private:\r
-  void registerNode( Node n, bool hasPol, bool pol, bool beneathQuant = false );\r
-  void flatten( Node n, bool beneathQuant );\r
-private: //for completing match\r
-  std::vector< int > d_unassigned;\r
-  std::vector< TypeNode > d_unassigned_tn;\r
-  int d_unassigned_nvar;\r
-  int d_una_index;\r
-  std::vector< int > d_una_eqc_count;\r
-public:\r
-  QuantInfo() : d_mg( NULL ) {}\r
-  ~QuantInfo() { delete d_mg; }\r
-  std::vector< TNode > d_vars;\r
-  std::vector< TypeNode > d_var_types;\r
-  std::map< TNode, int > d_var_num;\r
-  std::vector< int > d_tsym_vars;\r
-  std::map< TNode, bool > d_inMatchConstraint;\r
-  std::map< int, std::vector< Node > > d_var_constraint[2];\r
-  int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }\r
-  bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }\r
-  int getNumVars() { return (int)d_vars.size(); }\r
-  TNode getVar( int i ) { return d_vars[i]; }\r
-\r
-  MatchGen * d_mg;\r
-  Node d_q;\r
-  std::map< int, MatchGen * > d_var_mg;\r
-  void reset_round( QuantConflictFind * p );\r
-public:\r
-  //initialize\r
-  void initialize( Node q, Node qn );\r
-  //current constraints\r
-  std::vector< TNode > d_match;\r
-  std::vector< TNode > d_match_term;\r
-  std::map< int, std::map< TNode, int > > d_curr_var_deq;\r
-  std::map< Node, bool > d_tconstraints;\r
-  int getCurrentRepVar( int v );\r
-  TNode getCurrentValue( TNode n );\r
-  TNode getCurrentExpValue( TNode n );\r
-  bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );\r
-  int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );\r
-  int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );\r
-  bool setMatch( QuantConflictFind * p, int v, TNode n );\r
-  bool isMatchSpurious( QuantConflictFind * p );\r
-  bool isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms );\r
-  bool entailmentTest( QuantConflictFind * p, Node lit, bool chEnt = true );\r
-  bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );\r
-  void revertMatch( std::vector< int >& assigned );\r
-  void debugPrintMatch( const char * c );\r
-  bool isConstrainedVar( int v );\r
-public:\r
-  void getMatch( std::vector< Node >& terms );\r
-};\r
-\r
-class QuantConflictFind : public QuantifiersModule\r
-{\r
-  friend class MatchGen;\r
-  friend class QuantInfo;\r
-  typedef context::CDChunkList<Node> NodeList;\r
-  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;\r
-private:\r
-  context::CDO< bool > d_conflict;\r
-  std::vector< Node > d_quant_order;\r
-  std::map< Kind, Node > d_zero;\r
-  //for storing nodes created during t-constraint solving (prevents memory leaks)\r
-  std::vector< Node > d_tempCache;\r
-private:\r
-  std::map< Node, Node > d_op_node;\r
-  int d_fid_count;\r
-  std::map< Node, int > d_fid;\r
-  Node mkEqNode( Node a, Node b );\r
-public:  //for ground terms\r
-  Node d_true;\r
-  Node d_false;\r
-  TNode getZero( Kind k );\r
-private:\r
-  Node evaluateTerm( Node n );\r
-  int evaluate( Node n, bool pref = false, bool hasPref = false );\r
-private:\r
-  //currently asserted quantifiers\r
-  NodeList d_qassert;\r
-  std::map< Node, QuantInfo > d_qinfo;\r
-private:  //for equivalence classes\r
-  // type -> list(eqc)\r
-  std::map< TypeNode, std::vector< TNode > > d_eqcs;\r
-  std::map< TypeNode, Node > d_model_basis;\r
-public:\r
-  enum {\r
-    effort_conflict,\r
-    effort_prop_eq,\r
-    effort_mc,\r
-  };\r
-  short d_effort;\r
-  void setEffort( int e ) { d_effort = e; }\r
-  static short getMaxQcfEffort();\r
-  bool areMatchEqual( TNode n1, TNode n2 );\r
-  bool areMatchDisequal( TNode n1, TNode n2 );\r
-public:\r
-  QuantConflictFind( QuantifiersEngine * qe, context::Context* c );\r
-  ~QuantConflictFind() throw() {}\r
-  /** register quantifier */\r
-  void registerQuantifier( Node q );\r
-public:\r
-  /** assert quantifier */\r
-  void assertNode( Node q );\r
-  /** new node */\r
-  void newEqClass( Node n );\r
-  /** merge */\r
-  void merge( Node a, Node b );\r
-  /** assert disequal */\r
-  void assertDisequal( Node a, Node b );\r
-  /** needs check */\r
-  bool needsCheck( Theory::Effort level );\r
-  /** reset round */\r
-  void reset_round( Theory::Effort level );\r
-  /** check */\r
-  void check( Theory::Effort level, unsigned quant_e );\r
-private:\r
-  bool d_needs_computeRelEqr;\r
-public:\r
-  void computeRelevantEqr();\r
-private:\r
-  void debugPrint( const char * c );\r
-  //for debugging\r
-  std::vector< Node > d_quants;\r
-  std::map< Node, int > d_quant_id;\r
-  void debugPrintQuant( const char * c, Node q );\r
-  void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );\r
-public:\r
-  /** statistics class */\r
-  class Statistics {\r
-  public:\r
-    IntStat d_inst_rounds;\r
-    IntStat d_conflict_inst;\r
-    IntStat d_prop_inst;\r
-    IntStat d_entailment_checks;\r
-    Statistics();\r
-    ~Statistics();\r
-  };\r
-  Statistics d_statistics;\r
-  /** Identify this module */\r
-  std::string identify() const { return "QcfEngine"; }\r
-};\r
-\r
-}\r
-}\r
-}\r
-\r
-#endif\r
+/*********************                                                        */
+/*! \file quant_conflict_find.h
+ ** \verbatim
+ ** Original author: Andrew Reynolds
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief quantifiers conflict find class
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef QUANT_CONFLICT_FIND
+#define QUANT_CONFLICT_FIND
+
+#include "context/cdhashmap.h"
+#include "context/cdchunk_list.h"
+#include "theory/quantifiers_engine.h"
+#include "theory/quantifiers/term_database.h"
+
+namespace CVC4 {
+namespace theory {
+namespace quantifiers {
+
+class QuantConflictFind;
+class QuantInfo;
+
+//match generator
+class MatchGen {
+  friend class QuantInfo;
+private:
+  //current children information
+  int d_child_counter;
+  //children of this object
+  std::vector< int > d_children_order;
+  unsigned getNumChildren() { return d_children.size(); }
+  MatchGen * getChild( int i ) { return &d_children[d_children_order[i]]; }
+  //MatchGen * getChild( int i ) { return &d_children[i]; }
+  //current matching information
+  std::vector< TermArgTrie * > d_qn;
+  std::vector< std::map< TNode, TermArgTrie >::iterator > d_qni;
+  bool doMatching( QuantConflictFind * p, QuantInfo * qi );
+  //for matching : each index is either a variable or a ground term
+  unsigned d_qni_size;
+  std::map< int, int > d_qni_var_num;
+  std::map< int, TNode > d_qni_gterm;
+  std::map< int, TNode > d_qni_gterm_rep;
+  std::map< int, int > d_qni_bound;
+  std::vector< int > d_qni_bound_except;
+  std::map< int, TNode > d_qni_bound_cons;
+  std::map< int, int > d_qni_bound_cons_var;
+  std::map< int, int >::iterator d_binding_it;
+  //std::vector< int > d_independent;
+  bool d_matched_basis;
+  bool d_binding;
+  //int getVarBindingVar();
+  std::map< int, Node > d_ground_eval;
+  //determine variable order
+  void determineVariableOrder( QuantInfo * qi, std::vector< int >& bvars );
+  void collectBoundVar( QuantInfo * qi, Node n, std::vector< int >& cbvars );
+public:
+  //type of the match generator
+  enum {
+    typ_invalid,
+    typ_ground,
+    typ_pred,
+    typ_eq,
+    typ_formula,
+    typ_var,
+    typ_ite_var,
+    typ_bool_var,
+    typ_tconstraint,
+    typ_tsym,
+  };
+  void debugPrintType( const char * c, short typ, bool isTrace = false );
+public:
+  MatchGen() : d_type( typ_invalid ){}
+  MatchGen( QuantInfo * qi, Node n, bool isVar = false );
+  bool d_tgt;
+  bool d_tgt_orig;
+  bool d_wasSet;
+  Node d_n;
+  std::vector< MatchGen > d_children;
+  short d_type;
+  bool d_type_not;
+  void reset_round( QuantConflictFind * p );
+  void reset( QuantConflictFind * p, bool tgt, QuantInfo * qi );
+  bool getNextMatch( QuantConflictFind * p, QuantInfo * qi );
+  bool getExplanation( QuantConflictFind * p, QuantInfo * qi, std::vector< Node >& exp );
+  Node getExplanationTerm( QuantConflictFind * p, QuantInfo * qi, Node t, std::vector< Node >& exp );
+  bool isValid() { return d_type!=typ_invalid; }
+  void setInvalid();
+
+  // is this term treated as UF application?
+  static bool isHandledBoolConnective( TNode n );
+  static bool isHandledUfTerm( TNode n );
+  static Node getOperator( QuantConflictFind * p, Node n );
+  //can this node be handled by the algorithm
+  static bool isHandled( TNode n );
+};
+
+//info for quantifiers
+class QuantInfo {
+private:
+  void registerNode( Node n, bool hasPol, bool pol, bool beneathQuant = false );
+  void flatten( Node n, bool beneathQuant );
+private: //for completing match
+  std::vector< int > d_unassigned;
+  std::vector< TypeNode > d_unassigned_tn;
+  int d_unassigned_nvar;
+  int d_una_index;
+  std::vector< int > d_una_eqc_count;
+public:
+  QuantInfo() : d_mg( NULL ) {}
+  ~QuantInfo() { delete d_mg; }
+  std::vector< TNode > d_vars;
+  std::vector< TypeNode > d_var_types;
+  std::map< TNode, int > d_var_num;
+  std::vector< int > d_tsym_vars;
+  std::map< TNode, bool > d_inMatchConstraint;
+  std::map< int, std::vector< Node > > d_var_constraint[2];
+  int getVarNum( TNode v ) { return d_var_num.find( v )!=d_var_num.end() ? d_var_num[v] : -1; }
+  bool isVar( TNode v ) { return d_var_num.find( v )!=d_var_num.end(); }
+  int getNumVars() { return (int)d_vars.size(); }
+  TNode getVar( int i ) { return d_vars[i]; }
+
+  MatchGen * d_mg;
+  Node d_q;
+  std::map< int, MatchGen * > d_var_mg;
+  void reset_round( QuantConflictFind * p );
+public:
+  //initialize
+  void initialize( Node q, Node qn );
+  //current constraints
+  std::vector< TNode > d_match;
+  std::vector< TNode > d_match_term;
+  std::map< int, std::map< TNode, int > > d_curr_var_deq;
+  std::map< Node, bool > d_tconstraints;
+  int getCurrentRepVar( int v );
+  TNode getCurrentValue( TNode n );
+  TNode getCurrentExpValue( TNode n );
+  bool getCurrentCanBeEqual( QuantConflictFind * p, int v, TNode n, bool chDiseq = false );
+  int addConstraint( QuantConflictFind * p, int v, TNode n, bool polarity );
+  int addConstraint( QuantConflictFind * p, int v, TNode n, int vn, bool polarity, bool doRemove );
+  bool setMatch( QuantConflictFind * p, int v, TNode n );
+  bool isMatchSpurious( QuantConflictFind * p );
+  bool isTConstraintSpurious( QuantConflictFind * p, std::vector< Node >& terms );
+  bool entailmentTest( QuantConflictFind * p, Node lit, bool chEnt = true );
+  bool completeMatch( QuantConflictFind * p, std::vector< int >& assigned, bool doContinue = false );
+  void revertMatch( std::vector< int >& assigned );
+  void debugPrintMatch( const char * c );
+  bool isConstrainedVar( int v );
+public:
+  void getMatch( std::vector< Node >& terms );
+};
+
+class QuantConflictFind : public QuantifiersModule
+{
+  friend class MatchGen;
+  friend class QuantInfo;
+  typedef context::CDChunkList<Node> NodeList;
+  typedef context::CDHashMap<Node, bool, NodeHashFunction> NodeBoolMap;
+private:
+  context::CDO< bool > d_conflict;
+  std::vector< Node > d_quant_order;
+  std::map< Kind, Node > d_zero;
+  //for storing nodes created during t-constraint solving (prevents memory leaks)
+  std::vector< Node > d_tempCache;
+private:
+  std::map< Node, Node > d_op_node;
+  int d_fid_count;
+  std::map< Node, int > d_fid;
+  Node mkEqNode( Node a, Node b );
+public:  //for ground terms
+  Node d_true;
+  Node d_false;
+  TNode getZero( Kind k );
+private:
+  Node evaluateTerm( Node n );
+  int evaluate( Node n, bool pref = false, bool hasPref = false );
+private:
+  //currently asserted quantifiers
+  NodeList d_qassert;
+  std::map< Node, QuantInfo > d_qinfo;
+private:  //for equivalence classes
+  // type -> list(eqc)
+  std::map< TypeNode, std::vector< TNode > > d_eqcs;
+  std::map< TypeNode, Node > d_model_basis;
+public:
+  enum {
+    effort_conflict,
+    effort_prop_eq,
+    effort_mc,
+  };
+  short d_effort;
+  void setEffort( int e ) { d_effort = e; }
+  static short getMaxQcfEffort();
+  bool areMatchEqual( TNode n1, TNode n2 );
+  bool areMatchDisequal( TNode n1, TNode n2 );
+public:
+  QuantConflictFind( QuantifiersEngine * qe, context::Context* c );
+  ~QuantConflictFind() throw() {}
+  /** register quantifier */
+  void registerQuantifier( Node q );
+public:
+  /** assert quantifier */
+  void assertNode( Node q );
+  /** new node */
+  void newEqClass( Node n );
+  /** merge */
+  void merge( Node a, Node b );
+  /** assert disequal */
+  void assertDisequal( Node a, Node b );
+  /** needs check */
+  bool needsCheck( Theory::Effort level );
+  /** reset round */
+  void reset_round( Theory::Effort level );
+  /** check */
+  void check( Theory::Effort level, unsigned quant_e );
+private:
+  bool d_needs_computeRelEqr;
+public:
+  void computeRelevantEqr();
+private:
+  void debugPrint( const char * c );
+  //for debugging
+  std::vector< Node > d_quants;
+  std::map< Node, int > d_quant_id;
+  void debugPrintQuant( const char * c, Node q );
+  void debugPrintQuantBody( const char * c, Node q, Node n, bool doVarNum = true );
+public:
+  /** statistics class */
+  class Statistics {
+  public:
+    IntStat d_inst_rounds;
+    IntStat d_conflict_inst;
+    IntStat d_prop_inst;
+    IntStat d_entailment_checks;
+    Statistics();
+    ~Statistics();
+  };
+  Statistics d_statistics;
+  /** Identify this module */
+  std::string identify() const { return "QcfEngine"; }
+};
+
+}
+}
+}
+
+#endif
index 15c36682ced26d233475a6ead7fc2906b1cd67e5..f145013d8539a7edec338ac2b123460b5e1d380c 100644 (file)
@@ -1,20 +1,20 @@
-(set-logic UFC)\r
-(set-info :status unsat)\r
-\r
-(declare-sort P 0)\r
-(declare-sort H 0)\r
-\r
-(declare-fun p () P)\r
-(declare-fun h () H)\r
-\r
-; pigeonhole using native cardinality constraints\r
-(assert (fmf.card p 19))\r
-(assert (not (fmf.card p 18)))\r
-(assert (fmf.card h 18))\r
-(assert (not (fmf.card h 17)))\r
-\r
-; each pigeon has different holes\r
-(declare-fun f (P) H)\r
-(assert (forall ((p1 P) (p2 P)) (=> (not (= p1 p2)) (not (= (f p1) (f p2))))))\r
-\r
+(set-logic UFC)
+(set-info :status unsat)
+
+(declare-sort P 0)
+(declare-sort H 0)
+
+(declare-fun p () P)
+(declare-fun h () H)
+
+; pigeonhole using native cardinality constraints
+(assert (fmf.card p 19))
+(assert (not (fmf.card p 18)))
+(assert (fmf.card h 18))
+(assert (not (fmf.card h 17)))
+
+; each pigeon has different holes
+(declare-fun f (P) H)
+(assert (forall ((p1 P) (p2 P)) (=> (not (= p1 p2)) (not (= (f p1) (f p2))))))
+
 (check-sat)
\ No newline at end of file
index f1721cb04c3eb064fde4e984f83c711e46f83a33..2d4000e6ef008268dfe26d1ab204421c1e46d97b 100644 (file)
@@ -1,20 +1,20 @@
-(set-logic QF_UFC)\r
-(set-info :status unsat)\r
-\r
-(declare-sort U 0)\r
-\r
-(declare-fun a () U)\r
-(declare-fun b () U)\r
-(declare-fun c () U)\r
-(declare-fun d () U)\r
-(declare-fun e () U)\r
-\r
-(assert (not (= a b)))\r
-(assert (not (= b c)))\r
-(assert (not (= c d)))\r
-(assert (not (= d e)))\r
-(assert (not (= e a)))\r
-\r
-(assert (fmf.card c 2))\r
-\r
+(set-logic QF_UFC)
+(set-info :status unsat)
+
+(declare-sort U 0)
+
+(declare-fun a () U)
+(declare-fun b () U)
+(declare-fun c () U)
+(declare-fun d () U)
+(declare-fun e () U)
+
+(assert (not (= a b)))
+(assert (not (= b c)))
+(assert (not (= c d)))
+(assert (not (= d e)))
+(assert (not (= e a)))
+
+(assert (fmf.card c 2))
+
 (check-sat)
\ No newline at end of file
index d946974ed17bf9e7cb2a2190c6d410e6f78149aa..0d438f71803b74ed6fe3e32f589eca5fc81d8bb9 100644 (file)
@@ -1,14 +1,14 @@
-(set-logic UFC)\r
-(set-info :status unsat)\r
-\r
-(declare-sort U 0)\r
-\r
-(declare-fun a () U)\r
-(declare-fun b () U)\r
-(declare-fun c () U)\r
-\r
-(assert (not (fmf.card a 2)))\r
-\r
-(assert (forall ((x U)) (or (= x a) (= x b))))\r
-\r
+(set-logic UFC)
+(set-info :status unsat)
+
+(declare-sort U 0)
+
+(declare-fun a () U)
+(declare-fun b () U)
+(declare-fun c () U)
+
+(assert (not (fmf.card a 2)))
+
+(assert (forall ((x U)) (or (= x a) (= x b))))
+
 (check-sat)
\ No newline at end of file
index 366559b9db20f4377d042dc2d2b698372bdbd368..380a66aac17c20e3a5c4e14b755f5bc80d508039 100644 (file)
@@ -1,7 +1,7 @@
-(set-logic UFLIRA)\r
-(set-info :status unsat)\r
-; ensure that E-matching matches on sub-types\r
-(declare-fun P (Real) Bool)\r
-(assert (forall ((x Real)) (P x)))\r
-(assert (not (P 5)))\r
+(set-logic UFLIRA)
+(set-info :status unsat)
+; ensure that E-matching matches on sub-types
+(declare-fun P (Real) Bool)
+(assert (forall ((x Real)) (P x)))
+(assert (not (P 5)))
 (check-sat)
\ No newline at end of file
index 616189d96bf7b1151cebc8c0f9b8718a79330384..2ecbcc99301e49da381d952a858e416bfd1e814a 100644 (file)
@@ -1,12 +1,12 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-(declare-fun i () Int)\r
-\r
-(assert (= (str.at x i) "b"))\r
-(assert (and (>= i 4) (< i (str.len x))))\r
-(assert (< (str.len x) 7))\r
-(assert (> (str.len x) 2))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+
+(declare-fun x () String)
+(declare-fun i () Int)
+
+(assert (= (str.at x i) "b"))
+(assert (and (>= i 4) (< i (str.len x))))
+(assert (< (str.len x) 7))
+(assert (> (str.len x) 2))
+
+(check-sat)
index 49568329e85b177c59c87ee24a78f95c3d638ab5..cdeebd20bdf09883113c17b8fdfc72f430439261 100644 (file)
@@ -1,15 +1,15 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-(declare-fun z () String)\r
-\r
-(assert (= "\x4a" x))\r
-(assert (= "\x6a" y))\r
-\r
-(assert (= "\x4A" z))\r
-\r
-(assert (= x z))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+
+(declare-fun x () String)
+(declare-fun y () String)
+(declare-fun z () String)
+
+(assert (= "\x4a" x))
+(assert (= "\x6a" y))
+
+(assert (= "\x4A" z))
+
+(assert (= x z))
+
+(check-sat)
index 15d1ea5a2457419a29a6919e6e8d318433b2a911..f8a481e14f7f8f40942f45f1627f9f32fcc51bc9 100644 (file)
@@ -1,10 +1,10 @@
-(set-logic ASLIA)\r
-(set-info :smt-lib-version 2.0)\r
-(set-option :strings-exp true)\r
-(set-info :status sat)\r
-\r
-; regex = [\*-,\t\*-\|](.{6,}()?)+\r
-(define-fun strinre ((?s String)) Bool (str.in.re ?s (re.union re.nostr (re.++ (str.to.re "") (str.to.re "") (re.union re.nostr (re.range "*" ",") (str.to.re "\t") (re.range "*" "|") ) (re.+ (re.union re.nostr (re.++ (str.to.re "") (str.to.re "") (re.loop re.allchar 6 ) (re.opt (re.union re.nostr (re.++ (str.to.re "") (str.to.re "") ) ) ) ) ) ) ) )  ) )\r
-(assert (not (strinre "6O\1\127\n?")))\r
-\r
+(set-logic ASLIA)
+(set-info :smt-lib-version 2.0)
+(set-option :strings-exp true)
+(set-info :status sat)
+
+; regex = [\*-,\t\*-\|](.{6,}()?)+
+(define-fun strinre ((?s String)) Bool (str.in.re ?s (re.union re.nostr (re.++ (str.to.re "") (str.to.re "") (re.union re.nostr (re.range "*" ",") (str.to.re "\t") (re.range "*" "|") ) (re.+ (re.union re.nostr (re.++ (str.to.re "") (str.to.re "") (re.loop re.allchar 6 ) (re.opt (re.union re.nostr (re.++ (str.to.re "") (str.to.re "") ) ) ) ) ) ) ) )  ) )
+(assert (not (strinre "6O\1\127\n?")))
+
 (check-sat)
\ No newline at end of file
index aa2afb7e408f6353c81ca0b5415d51f5a143bbbe..67a184adeb43078779780e018416904b51a7a8a8 100644 (file)
@@ -1,12 +1,12 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-(set-info :smt-lib-version 2.0)\r
-\r
-(declare-fun x () String)\r
-(declare-const I Int)\r
-\r
-(assert (= x "\0\1\2\3\04\005\x06\7\8\9ABC\\\"\t\a\b"))\r
-(assert (= I (str.len x)))\r
-\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+(set-info :smt-lib-version 2.0)
+
+(declare-fun x () String)
+(declare-const I Int)
+
+(assert (= x "\0\1\2\3\04\005\x06\7\8\9ABC\\\"\t\a\b"))
+(assert (= I (str.len x)))
+
+
+(check-sat)
index f489953441ec41246329069ec991407974314282..af93a7ae5786fe24586bafa183cb66fd7d37d55e 100644 (file)
@@ -1,12 +1,12 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-(set-info :smt-lib-version 2.5)\r
-\r
-(declare-fun x () String)\r
-(declare-const I Int)\r
-\r
-(assert (= x "\0\1\2\3\04\005\x06\7\8\9ABC\\""\t\a\b"))\r
-(assert (= I (str.len x)))\r
-\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+(set-info :smt-lib-version 2.5)
+
+(declare-fun x () String)
+(declare-const I Int)
+
+(assert (= x "\0\1\2\3\04\005\x06\7\8\9ABC\\""\t\a\b"))
+(assert (= I (str.len x)))
+
+
+(check-sat)
index 05bbab58654f021e43a82776e1ad07f1c6b4ffbd..6081c8e06e69ece8abc5651944918610149424ad 100644 (file)
@@ -1,20 +1,20 @@
-(set-logic QF_S)\r
-(set-option :strings-exp true)\r
-(set-option :strings-fmf true)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-\r
-(assert (str.in.re x\r
-               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))\r
-       ))\r
-\r
-(assert (str.in.re y\r
-               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))\r
-       ))\r
-\r
-(assert (not (= x y)))\r
-(assert (= (str.len x) (str.len y)))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-option :strings-exp true)
+(set-option :strings-fmf true)
+(set-info :status sat)
+
+(declare-fun x () String)
+(declare-fun y () String)
+
+(assert (str.in.re x
+               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))
+       ))
+
+(assert (str.in.re y
+               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))
+       ))
+
+(assert (not (= x y)))
+(assert (= (str.len x) (str.len y)))
+
+(check-sat)
index 1d41b10856c43e883141b4443a86fb55756cfacb..d52dae2d2b1476985b71fcd5a52c846497f94c42 100644 (file)
@@ -1,17 +1,17 @@
-(set-logic QF_S)\r
-(set-option :strings-exp true)\r
-(set-option :strings-fmf true)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-(declare-fun z () String)\r
-\r
-(assert (str.in.re x\r
-                (re.+ (re.range "a" "c"))\r
-                                               ))\r
-\r
-(assert (= x (str.++ y "c" z "b")))\r
-(assert (> (str.len z) 1))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-option :strings-exp true)
+(set-option :strings-fmf true)
+(set-info :status sat)
+
+(declare-fun x () String)
+(declare-fun y () String)
+(declare-fun z () String)
+
+(assert (str.in.re x
+                (re.+ (re.range "a" "c"))
+                                               ))
+
+(assert (= x (str.++ y "c" z "b")))
+(assert (> (str.len z) 1))
+
+(check-sat)
index ae61b5f5b709df7d728516cc09ca0a4ef86d1b39..2889348c121d5eb67a1b46da9cb5f0d21d1a8ece 100644 (file)
@@ -1,11 +1,11 @@
-(set-logic QF_S)\r
-(set-option :strings-exp true)\r
-(set-info :status sat)\r
-\r
-(declare-fun Y () String)\r
-\r
-(assert (= Y "0001"))\r
-;(assert (= (str.to.int Y) (- 1)))\r
-(assert (= (str.to.int Y) 1))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-option :strings-exp true)
+(set-info :status sat)
+
+(declare-fun Y () String)
+
+(assert (= Y "0001"))
+;(assert (= (str.to.int Y) (- 1)))
+(assert (= (str.to.int Y) 1))
+
+(check-sat)
index 113577e483b92453ccd1a81a6b477aba1d318c69..f84ba442bdad8bb5852e73a7fa97e3197dfb13e2 100644 (file)
@@ -1,10 +1,10 @@
-(set-logic QF_S)\r
-(set-option :strings-exp true)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-\r
-(assert (= (str.++ x "ab") (str.++ "ba" x)))\r
-(assert (> (str.len x) 5))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-option :strings-exp true)
+(set-info :status sat)
+
+(declare-fun x () String)
+
+(assert (= (str.++ x "ab") (str.++ "ba" x)))
+(assert (> (str.len x) 5))
+
+(check-sat)
index 9ccc6de6e60bdaa4d735cc60bc921ccbbb775361..30fc6cebcd746dc23ecebf9702bf7f9b610e940d 100644 (file)
@@ -1,10 +1,10 @@
-(set-logic QF_S)\r
-(set-option :strings-exp true)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-\r
-(assert (= (str.++ x "aa") (str.++ "aa" x)))\r
-(assert (= (str.len x) 7))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-option :strings-exp true)
+(set-info :status sat)
+
+(declare-fun x () String)
+
+(assert (= (str.++ x "aa") (str.++ "aa" x)))
+(assert (= (str.len x) 7))
+
+(check-sat)
index 6a2044ea88876422cab93df4d631f14ec91f3d01..62c142d1da6b2fb80bf6d26cfd007af44814bc3c 100644 (file)
@@ -1,13 +1,13 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-(set-option :strings-exp true)\r
-\r
-(declare-fun x () String)\r
-\r
-(assert (str.in.re x\r
-               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))\r
-       ))\r
-\r
-(assert (= (str.len x) 3))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+(set-option :strings-exp true)
+
+(declare-fun x () String)
+
+(assert (str.in.re x
+               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))
+       ))
+
+(assert (= (str.len x) 3))
+
+(check-sat)
index 8c29ccb3825bff957ee1c0be334f8727eb6de86a..a8bd2187a5308606bb5f7416f80c4f54efaba969 100644 (file)
@@ -1,24 +1,24 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-(set-option :strings-exp true)\r
-; this option requires user to check whether the constraint is in the fragment\r
-; currently we do not provide only positive membership constraint checking\r
-; if users use this option but the constraint is not in this fragment, the result will fail\r
-(set-option :strings-inm true)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-\r
-(assert (str.in.re x\r
-               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))\r
-       ))\r
-\r
-(assert (str.in.re y\r
-               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))\r
-       ))\r
-\r
-(assert (not (= x y)))\r
-(assert (= (str.len x) (str.len y)))\r
-(assert (= (str.len y) 3))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+(set-option :strings-exp true)
+; this option requires user to check whether the constraint is in the fragment
+; currently we do not provide only positive membership constraint checking
+; if users use this option but the constraint is not in this fragment, the result will fail
+(set-option :strings-inm true)
+
+(declare-fun x () String)
+(declare-fun y () String)
+
+(assert (str.in.re x
+               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))
+       ))
+
+(assert (str.in.re y
+               (re.* (re.++ (re.* (str.to.re "a") ) (str.to.re "b") ))
+       ))
+
+(assert (not (= x y)))
+(assert (= (str.len x) (str.len y)))
+(assert (= (str.len y) 3))
+
+(check-sat)
index 6016899586114605bfa6eab1b0d5ae8cc14e0b02..7696838fe1d28d3cb9932d89bc362e48ccb01440 100644 (file)
@@ -1,13 +1,13 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-(set-option :strings-exp true)\r
-\r
-(declare-const s String)\r
-\r
-(assert (str.in.re s (re.inter\r
-       (re.++ (str.to.re "a") (re.* (str.to.re "b")) \r
-               (re.inter (str.to.re "c") (re.* (str.to.re "c"))))\r
-       (re.++ (str.to.re "a") (re.* (str.to.re "b")) (re.* (str.to.re "c")))\r
-       )))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+(set-option :strings-exp true)
+
+(declare-const s String)
+
+(assert (str.in.re s (re.inter
+       (re.++ (str.to.re "a") (re.* (str.to.re "b")) 
+               (re.inter (str.to.re "c") (re.* (str.to.re "c"))))
+       (re.++ (str.to.re "a") (re.* (str.to.re "b")) (re.* (str.to.re "c")))
+       )))
+
+(check-sat)
index 39b2b76b1159628b21bf946f0bb99b6b1c9266bf..9915504ae4889901c6f099deca43c09c2cff68b8 100644 (file)
@@ -1,18 +1,18 @@
-(set-logic QF_S)\r
-(set-option :strings-exp true)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-(declare-fun z () String)\r
-(declare-fun w () String)\r
-\r
-(assert (str.in.re x (re.loop (str.to.re "a") 5)))\r
-(assert (str.in.re y (re.loop (str.to.re "b") 2 5)))\r
-(assert (str.in.re z (re.loop (str.to.re "c") 5)))\r
-(assert (> (str.len z) 7))\r
-(assert (str.in.re w (re.loop (str.to.re "b") 2 7)))\r
-(assert (> (str.len w) 2))\r
-(assert (< (str.len w) 5))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-option :strings-exp true)
+(set-info :status sat)
+
+(declare-fun x () String)
+(declare-fun y () String)
+(declare-fun z () String)
+(declare-fun w () String)
+
+(assert (str.in.re x (re.loop (str.to.re "a") 5)))
+(assert (str.in.re y (re.loop (str.to.re "b") 2 5)))
+(assert (str.in.re z (re.loop (str.to.re "c") 5)))
+(assert (> (str.len z) 7))
+(assert (str.in.re w (re.loop (str.to.re "b") 2 7)))
+(assert (> (str.len w) 2))
+(assert (< (str.len w) 5))
+
+(check-sat)
index 592ef6a7fc072d89181444b51c6fc39e4b804773..2bdf9b1b5d1569fbe97e208941eb9b605e7e4fc1 100644 (file)
@@ -1,14 +1,14 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-(declare-fun z () String)\r
-\r
-;plandowski p469 1\r
-(assert (= (str.++ x "ab" y) (str.++ y "ba" z)))\r
-(assert (= z (str.++ x y)))\r
-(assert (not (= (str.++ x "a") (str.++ "a" x))))\r
-\r
-(check-sat)\r
-\r
+(set-logic QF_S)
+(set-info :status sat)
+
+(declare-fun x () String)
+(declare-fun y () String)
+(declare-fun z () String)
+
+;plandowski p469 1
+(assert (= (str.++ x "ab" y) (str.++ y "ba" z)))
+(assert (= z (str.++ x y)))
+(assert (not (= (str.++ x "a") (str.++ "a" x))))
+
+(check-sat)
+
index 0ca2ec4c386549601bf19748a54812f091511cfd..a7173701a19079b8698c413320b0c202f0f317c2 100644 (file)
@@ -1,13 +1,13 @@
-(set-logic QF_S)\r
-(set-info :status unsat)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-\r
-\r
-(assert (or (= x y) (= x y)))\r
-\r
-(assert (= (str.++ x "ba") (str.++ "ab" x)))\r
-(assert (= (str.++ y "ab") (str.++ "ab" y)))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status unsat)
+
+(declare-fun x () String)
+(declare-fun y () String)
+
+
+(assert (or (= x y) (= x y)))
+
+(assert (= (str.++ x "ba") (str.++ "ab" x)))
+(assert (= (str.++ y "ab") (str.++ "ab" y)))
+
+(check-sat)
index bdfa33afb7fb10eeedb1cb356f1f2ce7ba883233..78f3ffee766d2011f2504d01f3b937e6695b864b 100644 (file)
@@ -1,16 +1,16 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-\r
-(declare-fun x () String)\r
-(declare-fun i1 () Int)\r
-(declare-fun i2 () Int)\r
-(declare-fun i3 () Int)\r
-(declare-fun i4 () Int)\r
-\r
-(assert (and (>= i1 0) (>= i2 0) (< (+ i1 i2) (str.len x))))\r
-(assert (and (>= i3 0) (>= i4 0) (< (+ i3 i4) (str.len x))))\r
-(assert (= "efg" (str.substr x i1 i2) ) )\r
-(assert (= "bef" (str.substr x i3 i4) ) )\r
-(assert (> (str.len x) 5))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+
+(declare-fun x () String)
+(declare-fun i1 () Int)
+(declare-fun i2 () Int)
+(declare-fun i3 () Int)
+(declare-fun i4 () Int)
+
+(assert (and (>= i1 0) (>= i2 0) (< (+ i1 i2) (str.len x))))
+(assert (and (>= i3 0) (>= i4 0) (< (+ i3 i4) (str.len x))))
+(assert (= "efg" (str.substr x i1 i2) ) )
+(assert (= "bef" (str.substr x i3 i4) ) )
+(assert (> (str.len x) 5))
+
+(check-sat)
index ca93b00e5fd6cf8e12cfbbf605495e7195c689e9..77eabccccf14a41f8678cfc8a472fb73837f4912 100644 (file)
@@ -1,21 +1,21 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-(set-option :strings-exp true)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-(declare-fun i () Int)\r
-(declare-fun j () Int)\r
-(declare-fun z () String)\r
-\r
-;big num test\r
-(assert (= x (int.to.str 4785582390527685649)))\r
-;should be ""\r
-(assert (= y (int.to.str (- 9))))\r
-\r
-;big num\r
-(assert (= i (str.to.int "783914785582390527685649")))\r
-;should be -1\r
-(assert (= j (str.to.int "-783914785582390527685649")))\r
-\r
+(set-logic QF_S)
+(set-info :status sat)
+(set-option :strings-exp true)
+
+(declare-fun x () String)
+(declare-fun y () String)
+(declare-fun i () Int)
+(declare-fun j () Int)
+(declare-fun z () String)
+
+;big num test
+(assert (= x (int.to.str 4785582390527685649)))
+;should be ""
+(assert (= y (int.to.str (- 9))))
+
+;big num
+(assert (= i (str.to.int "783914785582390527685649")))
+;should be -1
+(assert (= j (str.to.int "-783914785582390527685649")))
+
 (check-sat)
\ No newline at end of file
index cbad2226a4b1399668a01181556e1be117f7b92b..296057a76ea861b902701746285e3b539997be32 100644 (file)
@@ -1,18 +1,18 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-(set-option :strings-exp true)\r
-\r
-(declare-fun x () String)\r
-(declare-fun y () String)\r
-(declare-fun z () String)\r
-(declare-fun i () Int)\r
-\r
-(assert (>= i 420))\r
-(assert (= x (u16.to.str i)))\r
-(assert (= x (str.++ y "0" z)))\r
-(assert (not (= y "")))\r
-(assert (not (= z "")))\r
-\r
-\r
-\r
+(set-logic QF_S)
+(set-info :status sat)
+(set-option :strings-exp true)
+
+(declare-fun x () String)
+(declare-fun y () String)
+(declare-fun z () String)
+(declare-fun i () Int)
+
+(assert (>= i 420))
+(assert (= x (u16.to.str i)))
+(assert (= x (str.++ y "0" z)))
+(assert (not (= y "")))
+(assert (not (= z "")))
+
+
+
 (check-sat)
\ No newline at end of file
index b8f0ac5aee5b3d8080a96061f7771a0df15f9007..c2d4792cc6bd0c227840f087f74d3ff3d3da5592 100644 (file)
@@ -1,12 +1,12 @@
-(set-logic QF_S)\r
-(set-info :status sat)\r
-(set-option :strings-exp true)\r
-\r
-(declare-fun i () Int)\r
-(declare-fun s () String)\r
-\r
-(assert (< 67 (str.to.int s)))\r
-(assert (= (str.len s) 2))\r
-(assert (not (= s "68")))\r
-\r
-(check-sat)\r
+(set-logic QF_S)
+(set-info :status sat)
+(set-option :strings-exp true)
+
+(declare-fun i () Int)
+(declare-fun s () String)
+
+(assert (< 67 (str.to.int s)))
+(assert (= (str.len s) 2))
+(assert (not (= s "68")))
+
+(check-sat)