Add smtbmc prove support
authorClifford Wolf <clifford@clifford.at>
Mon, 30 Jan 2017 11:59:20 +0000 (12:59 +0100)
committerClifford Wolf <clifford@clifford.at>
Mon, 30 Jan 2017 11:59:20 +0000 (12:59 +0100)
sbysrc/sby_core.py
sbysrc/sby_engine_smtbmc.py
sbysrc/sby_mode_prove.py

index d4903b9216e176683fe5a1001e50533a90f21174..3c713f8c9d369ded7e045a80d39b2acc19329900 100644 (file)
@@ -332,7 +332,7 @@ class SbyJob:
             import sby_mode_bmc
             sby_mode_bmc.run(self)
 
-        if self.options["mode"] == "prove":
+        elif self.options["mode"] == "prove":
             import sby_mode_prove
             sby_mode_prove.run(self)
 
index 8b30255ada55c8e5c1e014b6c7b186f03b4adee4..65ebbc6c82eac86e629963f13fa49d7f00003964 100644 (file)
@@ -20,8 +20,6 @@ import re, os, getopt
 from sby_core import SbyTask
 
 def run(mode, job, engine_idx, engine):
-    assert mode == "bmc"
-
     smtbmc_opts = []
     nomem_opt = False
     syn_opt = False
@@ -43,11 +41,34 @@ def run(mode, job, engine_idx, engine):
     if syn_opt: model_name += "_syn"
     if nomem_opt: model_name += "_nomem"
 
-    task = SbyTask(job, "engine_%d" % engine_idx, job.model(model_name),
-            ("cd %s; yosys-smtbmc --noprogress %s -t %d --dump-vcd engine_%d/trace.vcd --dump-vlogtb engine_%d/trace_tb.v " +
-             "--dump-smtc engine_%d/trace.smtc model/design_smt2.smt2") %
-                    (job.workdir, " ".join(smtbmc_opts), job.opt_depth, engine_idx, engine_idx, engine_idx),
-            logfile=open("%s/engine_%d/logfile.txt" % (job.workdir, engine_idx), "w"))
+    if mode == "prove":
+        run("prove_basecase", job, engine_idx, engine)
+        run("prove_induction", job, engine_idx, engine)
+        return
+
+    taskname = "engine_%d" % engine_idx
+    trace_prefix = "engine_%d/trace" % engine_idx
+    logfile_prefix = "%s/engine_%d/logfile" % (job.workdir, engine_idx)
+
+    if mode == "prove_basecase":
+        taskname += ".basecase"
+
+    if mode == "prove_induction":
+        taskname += ".induction"
+        trace_prefix += "_induct"
+        logfile_prefix += "_induct"
+        smtbmc_opts.append("-i")
+
+    task = SbyTask(job, taskname, job.model(model_name),
+            ("cd %s; yosys-smtbmc --noprogress %s -t %d --dump-vcd %s.vcd --dump-vlogtb %s_tb.v --dump-smtc %s.smtc model/design_smt2.smt2") %
+                    (job.workdir, " ".join(smtbmc_opts), job.opt_depth, trace_prefix, trace_prefix, trace_prefix),
+            logfile=open(logfile_prefix + ".txt", "w"))
+
+    if mode == "prove_basecase":
+        job.basecase_tasks.append(task)
+
+    if mode == "prove_induction":
+        job.induction_tasks.append(task)
 
     task_status = None
 
@@ -63,14 +84,49 @@ def run(mode, job, engine_idx, engine):
     def exit_callback(retcode):
         assert task_status is not None
 
-        job.status = task_status
-        job.log("engine_%d: Status returned by engine: %s" % (engine_idx, task_status))
-        job.summary.append("engine_%d (%s) returned %s" % (engine_idx, " ".join(engine), job.status))
+        if mode == "bmc":
+            job.status = task_status
+            job.log("engine_%d: Status returned by engine: %s" % (engine_idx, task_status))
+            job.summary.append("engine_%d (%s) returned %s" % (engine_idx, " ".join(engine), job.status))
+
+            if job.status == "FAIL":
+                job.summary.append("counterexample trace: %s/engine_%d/trace.vcd" % (job.workdir, engine_idx))
+
+            job.terminate()
 
-        if job.status == "FAIL":
-            job.summary.append("counterexample trace: %s/engine_%d/trace.vcd" % (job.workdir, engine_idx))
+        elif mode in ["prove_basecase", "prove_induction"]:
+            job.log("engine_%d: Status returned by engine for %s: %s" % (engine_idx, mode.split("_")[1], task_status))
+            job.summary.append("engine_%d (%s) returned %s for %s" % (engine_idx, " ".join(engine), task_status, mode.split("_")[1]))
 
-        job.terminate()
+            if mode == "prove_basecase":
+                for task in job.basecase_tasks:
+                    task.terminate()
+
+                if task_status == "PASS":
+                    job.basecase_pass = True
+
+                else:
+                    job.status = task_status
+                    job.summary.append("counterexample trace: %s/engine_%d/trace.vcd" % (job.workdir, engine_idx))
+                    job.terminate()
+
+            elif mode == "prove_induction":
+                for task in job.induction_tasks:
+                    task.terminate()
+
+                if task_status == "PASS":
+                    job.induction_pass = True
+
+            else:
+                assert False
+
+            if job.basecase_pass and job.induction_pass:
+                job.status = "PASS"
+                job.summary.append("successful proof by k-induction.")
+                job.terminate()
+
+        else:
+            assert False
 
     task.output_callback = output_callback
     task.exit_callback = exit_callback
index 45b05e74ac67f7feec31c216a760c75a48c6a753..2491404b5fdbceb6d42098ff71adddc4ab9969cf 100644 (file)
@@ -25,8 +25,10 @@ def run(job):
     if "depth" in job.options:
         job.opt_depth = int(job.options["depth"])
 
-    job.basecase_done = False
-    job.induction_done = False
+    job.status = "UNKNOWN"
+
+    job.basecase_pass = False
+    job.induction_pass = False
     job.basecase_tasks = list()
     job.induction_tasks = list()