| 1 | % (c) 2014-2026 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, | |
| 2 | % Heinrich Heine Universitaet Duesseldorf | |
| 3 | % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) | |
| 4 | ||
| 5 | :- module(smtlib2_cli,[smtlib2_file/1, smtlib2_file/2, get_smtlib2_result_infos/1]). | |
| 6 | ||
| 7 | :- use_module(probsrc(module_information),[module_info/2]). | |
| 8 | :- module_info(group,smtlib). | |
| 9 | :- module_info(description,'Command line interface and REPL for SMT-LIB 2 files.'). | |
| 10 | ||
| 11 | :- use_module(smtlib_solver(smtlib2_interpreter)). | |
| 12 | :- use_module(smtlib_solver(smtlib2_parser)). | |
| 13 | :- use_module(smtlib_solver(smtlib2_environment)). | |
| 14 | ||
| 15 | :- use_module(probsrc(debug),[debug_println/2]). | |
| 16 | :- use_module(probsrc(preferences), [set_preference/2]). | |
| 17 | :- use_module(probsrc(error_manager),[add_error/3]). | |
| 18 | ||
| 19 | :- set_prolog_flag(double_quotes, codes). | |
| 20 | ||
| 21 | read_file(Stream,Out) :- | |
| 22 | get_code(Stream,Code), | |
| 23 | read_file(Code,Stream,Out). | |
| 24 | read_file(-1,_Stream,[]) :- !. | |
| 25 | read_file(Code,Stream,[Code|L]) :- | |
| 26 | read_file(Stream,L). | |
| 27 | ||
| 28 | smtlib2_file(Filename) :- smtlib2_file(Filename,[]). | |
| 29 | ||
| 30 | smtlib2_file(Filename,Options) :- | |
| 31 | debug_println(10,processing_smt_file(Filename)), | |
| 32 | % enable disprover mode to trigger modified treatment of wd conditions, etc. | |
| 33 | % some default preferences | |
| 34 | set_preference(disprover_mode,true), | |
| 35 | set_preference(use_clpfd_solver,true), | |
| 36 | set_preference(use_smt_mode,true), | |
| 37 | ||
| 38 | debug_println(25,opening(Filename)), | |
| 39 | open(Filename,read,S), | |
| 40 | read_file(S,Content), | |
| 41 | close(S),!, | |
| 42 | smtlib2_file(Filename,Content,Options). | |
| 43 | smtlib2_file(Filename,_) :- | |
| 44 | add_error(smtlib2_cli,'Could not read SMTLib file: ',Filename). | |
| 45 | ||
| 46 | smtlib2_file(Filename,Content,Options) :- | |
| 47 | debug_println(25,parsing(Filename)), | |
| 48 | parse_smtlib2(Content,ListOfCommands), | |
| 49 | !, | |
| 50 | empty_env(EnvIn), | |
| 51 | debug_println(25,interpreting_commands(ListOfCommands)), | |
| 52 | catch( | |
| 53 | ( | |
| 54 | interpret_l(ListOfCommands,EnvIn,EnvOut), | |
| 55 | (member(repl,Options) | |
| 56 | -> debug_println(25,finished_processing_and_starting_repl(Filename)), | |
| 57 | repl_help, | |
| 58 | smtlib2_repl(EnvOut) | |
| 59 | ; true) | |
| 60 | ), | |
| 61 | halt(0), | |
| 62 | debug_println(25,finished_processing_exit(Filename)) | |
| 63 | ). | |
| 64 | smtlib2_file(Filename,_,_) :- | |
| 65 | add_error(smtlib2_cli,'Could not parse SMTLib file: ',Filename). | |
| 66 | ||
| 67 | :- use_module(probsrc(tools_printing),[format_with_colour/4]). | |
| 68 | ||
| 69 | repl_help :- | |
| 70 | format_with_colour(user_output,[blue],'Starting SMTLIB REPL~n',[]), | |
| 71 | format_with_colour(user_output,[blue],'Available commands:~n',[]), | |
| 72 | format_with_colour(user_output,[blue],' (get-model)~n',[]), | |
| 73 | format_with_colour(user_output,[blue],' (check-sat)~n',[]), | |
| 74 | format_with_colour(user_output,[blue],' (set-info I Val)~n',[]), | |
| 75 | format_with_colour(user_output,[blue],' (push Num)~n',[]), | |
| 76 | format_with_colour(user_output,[blue],' (pop Num)~n',[]), | |
| 77 | format_with_colour(user_output,[blue],' (assert Term)~n',[]), | |
| 78 | format_with_colour(user_output,[blue],' (reset)~n',[]), | |
| 79 | format_with_colour(user_output,[blue],' (exit)~n',[]), | |
| 80 | format_with_colour(user_output,[blue],' define-fun, declare-sort,....~n~n',[]). | |
| 81 | ||
| 82 | smtlib2_repl(EnvIn) :- | |
| 83 | write('SMT>>>'),flush_output(user_output), | |
| 84 | read_line(Line), | |
| 85 | (Line = end_of_file -> halt(0) | |
| 86 | ; append(RealLine,".",Line) -> true | |
| 87 | ; RealLine = Line | |
| 88 | ), | |
| 89 | (parse_smtlib2(RealLine,Commands) | |
| 90 | -> (interpret_l(Commands,EnvIn,EnvOut) -> true | |
| 91 | ; format_with_colour(user_output,[red],'Could not process SMT commands: ~w~n',[Commands]) | |
| 92 | ) | |
| 93 | ; atom_codes(RL,RealLine), | |
| 94 | add_error(smtlib2_cli,'Parser error on line: ',RL) | |
| 95 | ), | |
| 96 | smtlib2_repl(EnvOut). | |
| 97 | ||
| 98 | ||
| 99 | ||
| 100 | % get result in format for accumulate_infos of prob_cli | |
| 101 | get_smtlib2_result_infos([lines-L,sat-S,unsat-U,unknown-UK]) :- | |
| 102 | smtlib2_result(Res),!, get_smtlib_lines_read(L), | |
| 103 | (Res = sat -> S=1,U=0,UK=0 | |
| 104 | ; Res=unsat -> S=0, U=1, UK=0 | |
| 105 | ; UK=1, S=0, U=0). | |
| 106 | get_smtlib2_result_infos([lines-L,sat-0,unsat-0,unknown-0]) :- get_smtlib_lines_read(L). |