From f07ec4f209a4cc85f298742586cc54fd9bc76fc3 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Tue, 18 Nov 2025 10:08:50 -0800 Subject: [PATCH 1/2] ebmc language implementation for SMV This adds an implementation of the ebmc_languaget interface for SMV. --- src/smvlang/Makefile | 3 +- src/smvlang/smv_ebmc_language.cpp | 109 ++++++++++++++++++++++++++++++ src/smvlang/smv_ebmc_language.h | 34 ++++++++++ src/smvlang/smv_parse_tree.h | 1 + 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 src/smvlang/smv_ebmc_language.cpp create mode 100644 src/smvlang/smv_ebmc_language.h diff --git a/src/smvlang/Makefile b/src/smvlang/Makefile index 248dced76..30b6e6505 100644 --- a/src/smvlang/Makefile +++ b/src/smvlang/Makefile @@ -1,4 +1,5 @@ -SRC = smv_expr.cpp \ +SRC = smv_ebmc_language.cpp \ + smv_expr.cpp \ smv_language.cpp \ smv_parser.cpp \ smv_typecheck.cpp \ diff --git a/src/smvlang/smv_ebmc_language.cpp b/src/smvlang/smv_ebmc_language.cpp new file mode 100644 index 000000000..2177c062a --- /dev/null +++ b/src/smvlang/smv_ebmc_language.cpp @@ -0,0 +1,109 @@ +/*******************************************************************\ + +Module: SMV Language Interface + +Author: Daniel Kroening, dkr@amazon.com + +\*******************************************************************/ + +/// \file +/// SMV Language Interface + +#include "smv_ebmc_language.h" + +#include +#include +#include + +#include +#include + +#include "smv_parser.h" +#include "smv_typecheck.h" + +#include +#include + +std::string smv_file_name(const cmdlinet &cmdline) +{ + if(cmdline.args.size() == 0) + throw ebmc_errort{} << "no file name given"; + + if(cmdline.args.size() >= 2) + throw ebmc_errort{}.with_exit_code(1) << "SMV only uses a single file"; + + return cmdline.args.front(); +} + +smv_parse_treet smv_ebmc_languaget::parse() +{ + smv_parsert smv_parser{message_handler}; + + auto file_name = smv_file_name(cmdline); + + std::ifstream infile{widen_if_needed(file_name)}; + + if(!infile) + throw ebmc_errort{}.with_exit_code(1) << "failed to open " << file_name; + + smv_parser.set_file(file_name); + smv_parser.in = &infile; + + if(smv_parser.parse()) + throw ebmc_errort{}.with_exit_code(1); + + return std::move(smv_parser.parse_tree); +} + +std::optional smv_ebmc_languaget::transition_system() +{ + if(cmdline.isset("preprocess")) + { + throw ebmc_errort{}.with_exit_code(1) << "SMV does not use preprocessing"; + } + + auto parse_tree = parse(); + + if(cmdline.isset("show-parse")) + { + parse_tree.show(std::cout); + return {}; + } + + if( + cmdline.isset("show-modules") || cmdline.isset("modules-xml") || + cmdline.isset("json-modules")) + { + //show_modules(cmdline, message_handler); + return {}; + } + + if(cmdline.isset("show-module-hierarchy")) + { + //show_module_hierarchy(cmdline, message_handler); + return {}; + } + + transition_systemt result; + + if(smv_typecheck( + parse_tree, result.symbol_table, "smv::main", message_handler)) + { + messaget message{message_handler}; + message.error() << "CONVERSION ERROR" << messaget::eom; + throw ebmc_errort{}.with_exit_code(2); + } + + if(cmdline.isset("show-symbol-table")) + { + std::cout << result.symbol_table; + return {}; + } + + result.main_symbol = + &get_module(result.symbol_table, "main", message_handler); + + result.trans_expr = to_trans_expr(result.main_symbol->value); + + return result; +} diff --git a/src/smvlang/smv_ebmc_language.h b/src/smvlang/smv_ebmc_language.h new file mode 100644 index 000000000..72ab3ef35 --- /dev/null +++ b/src/smvlang/smv_ebmc_language.h @@ -0,0 +1,34 @@ +/*******************************************************************\ + +Module: SMV Language Interface + +Author: Daniel Kroening, dkr@amazon.com + +\*******************************************************************/ + +/// \file +/// SMV Language Interface + +#ifndef EBMC_SMV_LANGUAGE_H +#define EBMC_SMV_LANGUAGE_H + +#include + +class smv_parse_treet; + +class smv_ebmc_languaget : public ebmc_languaget +{ +public: + smv_ebmc_languaget(cmdlinet &_cmdline, message_handlert &_message_handler) + : ebmc_languaget(_cmdline, _message_handler) + { + } + + // produce the transition system, and return it + std::optional transition_system() override; + +protected: + smv_parse_treet parse(); +}; + +#endif // EBMC_SMV_LANGUAGE_H diff --git a/src/smvlang/smv_parse_tree.h b/src/smvlang/smv_parse_tree.h index 80500cb9b..2c82bf3f1 100644 --- a/src/smvlang/smv_parse_tree.h +++ b/src/smvlang/smv_parse_tree.h @@ -20,6 +20,7 @@ class smv_parse_treet { public: smv_parse_treet() = default; + smv_parse_treet(smv_parse_treet &&) = default; // don't copy, contains pointers smv_parse_treet(const smv_parse_treet &) = delete; From 18618b8b1cf54a2521104da87f6d7bae537186f5 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Tue, 18 Nov 2025 21:27:00 -0800 Subject: [PATCH 2/2] use SMV language interface --- src/ebmc/build_transition_system.cpp | 84 ++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/src/ebmc/build_transition_system.cpp b/src/ebmc/build_transition_system.cpp index 1471e2a1f..f14dc10b6 100644 --- a/src/ebmc/build_transition_system.cpp +++ b/src/ebmc/build_transition_system.cpp @@ -18,6 +18,7 @@ Author: Daniel Kroening, dkr@amazon.com #include #include #include +#include #include #include @@ -335,39 +336,76 @@ int show_symbol_table( cmdline, message_handler, dummy_transition_system); } -std::optional ebmc_languagest::transition_system() +static std::set file_extensions(const cmdlinet::argst &args) { - if(cmdline.isset("preprocess")) - { - preprocess(cmdline, message_handler); - return {}; - } + std::set result; - if(cmdline.isset("show-parse")) + for(auto &arg : args) { - show_parse(cmdline, message_handler); - return {}; + std::size_t ext_pos = arg.rfind('.'); + + if(ext_pos != std::string::npos) + { + auto ext = std::string(arg, ext_pos + 1, std::string::npos); + result.insert(ext); + } } - if( - cmdline.isset("show-modules") || cmdline.isset("modules-xml") || - cmdline.isset("json-modules")) + return result; +} + +std::optional ebmc_languagest::transition_system() +{ + auto extensions = file_extensions(cmdline.args); + auto ext_used = [&extensions](const char *ext) + { return extensions.find(ext) != extensions.end(); }; + + bool have_smv = ext_used("smv"); + bool have_verilog = ext_used("v") || ext_used("sv"); + + if(have_smv && have_verilog) { - show_modules(cmdline, message_handler); - return {}; + throw ebmc_errort{} << "no support for mixed-language models"; } - if(cmdline.isset("show-module-hierarchy")) + if(have_smv) { - show_module_hierarchy(cmdline, message_handler); - return {}; + return smv_ebmc_languaget{cmdline, message_handler}.transition_system(); } - - if(cmdline.isset("show-symbol-table")) + else { - show_symbol_table(cmdline, message_handler); - return {}; + if(cmdline.isset("preprocess")) + { + preprocess(cmdline, message_handler); + return {}; + } + + if(cmdline.isset("show-parse")) + { + show_parse(cmdline, message_handler); + return {}; + } + + if( + cmdline.isset("show-modules") || cmdline.isset("modules-xml") || + cmdline.isset("json-modules")) + { + show_modules(cmdline, message_handler); + return {}; + } + + if(cmdline.isset("show-module-hierarchy")) + { + show_module_hierarchy(cmdline, message_handler); + return {}; + } + + if(cmdline.isset("show-symbol-table")) + { + show_symbol_table(cmdline, message_handler); + return {}; + } + + return get_transition_system(cmdline, message_handler); } - - return get_transition_system(cmdline, message_handler); }