pub fn call_boogie(&self, boogie_file: &str) -> anyhow::Result<BoogieOutput> {
        let args = self.options.get_boogie_command(boogie_file)?;
        info!("running solver");
        debug!("command line: {}", args.iter().join(" "));
        let task = RunBoogieWithSeeds {
            options: self.options.clone(),
            boogie_file: boogie_file.to_string(),
        };
        // When running on complicated formulas(especially those with quantifiers), SMT solvers
        // can suffer from the so-called butterfly effect, where minor changes such as using
        // different random seeds cause significant instabilities in verification times.
        // Thus by running multiple instances of Boogie with different random seeds, we can
        // potentially alleviate the instability.
        let (seed, output_res) = ProverTaskRunner::run_tasks(
            task,
            self.options.num_instances,
            self.options.sequential_task,
            self.options.hard_timeout_secs,
        );
        let output = match output_res {
            Err(err) => {
                if err.kind() == std::io::ErrorKind::TimedOut {
                    let err = BoogieError {
                        kind: BoogieErrorKind::Internal,
                        loc: self.env.unknown_loc(),
                        message: format!(
                            "Boogie execution exceeded hard timeout of {}s",
                            self.options.hard_timeout_secs
                        ),
                        execution_trace: vec![],
                        model: None,
                    };
                    return Ok(BoogieOutput {
                        errors: vec![err],
                        all_output: "".to_string(),
                    });
                } else {
                    panic!("cannot execute boogie `{:?}`: {}", args, err)
                }
            }
            Ok(out) => out,
        };
        if self.options.num_instances > 1 {
            debug!("Boogie instance with seed {} finished first", seed);
        }

        debug!("analyzing boogie output");
        let out = String::from_utf8_lossy(&output.stdout).to_string();
        let err = String::from_utf8_lossy(&output.stderr).to_string();
        // Boogie prints a few ad-hoc error messages (with exit code 0!), so we have
        // no chance to catch an error until we recognize one of those patterns.
        if out
            .trim()
            .starts_with("Fatal Error: ProverException: Cannot find specified prover")
        {
            return Err(anyhow!(
                "The configured prover `{}` could not be found{}",
                if self.options.use_cvc5 {
                    &self.options.cvc5_exe
                } else {
                    &self.options.z3_exe
                },
                if self.options.use_cvc5 {
                    " (--use-cvc5 is set)"
                } else {
                    ""
                }
            ));
        }
        if !output.status.success() {
            // Exit here with raw output.
            return Err(anyhow!(
                "Boogie error ({}): {}\n\nstderr:\n{}",
                output.status,
                out,
                err
            ));
        }
        if out.trim().starts_with("Unable to monomorphize") {
            return Err(anyhow!("Boogie error: {}\n\nstderr:\n{}", out, err));
        }
        // Boogie output contains the string "errors detected in" whenever parsing,
        // resolution, or type checking errors are discovered.
        if out.contains("errors detected in") {
            return Err(anyhow!(
                "[internal] boogie exited with compilation errors:\n{}",
                out
            ));
        }
        if out.contains("Prover error:") {
            return Err(anyhow!(
                "[internal] boogie exited with prover errors:\n{}",
                out
            ));
        }
        let mut errors = self.extract_verification_errors(&out);
        errors.extend(self.extract_inconclusive_errors(&out));
        errors.extend(self.extract_inconsistency_errors(&out));
        Ok(BoogieOutput {
            errors,
            all_output: out,
        })
    }
/// Calls boogie on the given file. On success, returns a struct representing the analyzed
/// output of boogie.
Calls boogie on the given file. On success, returns a struct representing the analyzed
output of boogie.
Calls boogie on the given file . On success returns a struct representing the analyzed output of boogie .
pub fn call_boogie(&self, boogie_file: &str) -> anyhow::Result<BoogieOutput> {
        let args = self.options.get_boogie_command(boogie_file)?;
        info!("running solver");
        debug!("command line: {}", args.iter().join(" "));
        let task = RunBoogieWithSeeds {
            options: self.options.clone(),
            boogie_file: boogie_file.to_string(),
        };
        // When running on complicated formulas(especially those with quantifiers), SMT solvers
        // can suffer from the so-called butterfly effect, where minor changes such as using
        // different random seeds cause significant instabilities in verification times.
        // Thus by running multiple instances of Boogie with different random seeds, we can
        // potentially alleviate the instability.
        let (seed, output_res) = ProverTaskRunner::run_tasks(
            task,
            self.options.num_instances,
            self.options.sequential_task,
            self.options.hard_timeout_secs,
        );
        let output = match output_res {
            Err(err) => {
                if err.kind() == std::io::ErrorKind::TimedOut {
                    let err = BoogieError {
                        kind: BoogieErrorKind::Internal,
                        loc: self.env.unknown_loc(),
                        message: format!(
                            "Boogie execution exceeded hard timeout of {}s",
                            self.options.hard_timeout_secs
                        ),
                        execution_trace: vec![],
                        model: None,
                    };
                    return Ok(BoogieOutput {
                        errors: vec![err],
                        all_output: "".to_string(),
                    });
                } else {
                    panic!("cannot execute boogie `{:?}`: {}", args, err)
                }
            }
            Ok(out) => out,
        };
        if self.options.num_instances > 1 {
            debug!("Boogie instance with seed {} finished first", seed);
        }
        debug!("analyzing boogie output");
        let out = String::from_utf8_lossy(&output.stdout).to_string();
        let err = String::from_utf8_lossy(&output.stderr).to_string();
        // Boogie prints a few ad-hoc error messages (with exit code 0!), so we have
        // no chance to catch an error until we recognize one of those patterns.
        if out
            .trim()
            .starts_with("Fatal Error: ProverException: Cannot find specified prover")
        {
            return Err(anyhow!(
                "The configured prover `{}` could not be found{}",
                if self.options.use_cvc5 {
                    &self.options.cvc5_exe
                } else {
                    &self.options.z3_exe
                },
                if self.options.use_cvc5 {
                    " (--use-cvc5 is set)"
                } else {
                    ""
                }
            ));
        }
        if !output.status.success() {
            // Exit here with raw output.
            return Err(anyhow!(
                "Boogie error ({}): {}\n\nstderr:\n{}",
                output.status,
                out,
                err
            ));
        }
        if out.trim().starts_with("Unable to monomorphize") {
            return Err(anyhow!("Boogie error: {}\n\nstderr:\n{}", out, err));
        }
        // Boogie output contains the string "errors detected in" whenever parsing,
        // resolution, or type checking errors are discovered.
        if out.contains("errors detected in") {
            return Err(anyhow!(
                "[internal] boogie exited with compilation errors:\n{}",
                out
            ));
        }
        if out.contains("Prover error:") {
            return Err(anyhow!(
                "[internal] boogie exited with prover errors:\n{}",
                out
            ));
        }
        let mut errors = self.extract_verification_errors(&out);
        errors.extend(self.extract_inconclusive_errors(&out));
        errors.extend(self.extract_inconsistency_errors(&out));
        Ok(BoogieOutput {
            errors,
            all_output: out,
        })
    }
pub fn call_boogie ( & self , boogie_file : & str ) -> anyhow :: Result < BoogieOutput > { let args = self . options . get_boogie_command ( boogie_file ) ? ; info ! ( " " ) ; debug ! ( " " args iter ( ) join ( " " ) ) ; let task = RunBoogieWithSeeds { options : self . options . clone ( ) , boogie_file : boogie_file . to_string ( ) , } ; // When running on complicated formulas(especially those with quantifiers), SMT solvers // can suffer from the so-called butterfly effect, where minor changes such as using // different random seeds cause significant instabilities in verification times. // Thus by running multiple instances of Boogie with different random seeds, we can // potentially alleviate the instability. let ( seed , output_res ) = ProverTaskRunner :: run_tasks ( task , self . options . num_instances , self . options . sequential_task , self . options . hard_timeout_secs , ) ; let output = match output_res { Err ( err ) => { if err . kind ( ) == std :: io :: ErrorKind :: TimedOut { let err = BoogieError { kind : BoogieErrorKind :: Internal , loc : self . env . unknown_loc ( ) , message : format ! ( " " self options hard_timeout_secs ) , execution_trace : vec ! [ ] , model : None , } ; return Ok ( BoogieOutput { errors : vec ! [ err ] , all_output : " " . to_string ( ) , } ) ; } else { panic ! ( " " args err ) } } Ok ( out ) => out , } ; if self . options . num_instances > 1 { debug ! ( " " seed ) ; } debug ! ( " " ) ; let out = String :: from_utf8_lossy ( & output . stdout ) . to_string ( ) ; let err = String :: from_utf8_lossy ( & output . stderr ) . to_string ( ) ; // Boogie prints a few ad-hoc error messages (with exit code 0!), so we have // no chance to catch an error until we recognize one of those patterns. if out . trim ( ) . starts_with ( " " ) { return Err ( anyhow ! ( " " if self options use_cvc5 { self options cvc5_exe } else { self options z3_exe } if self options use_cvc5 { " " } else { " " } ) ) ; } if ! output . status . success ( ) { // Exit here with raw output. return Err ( anyhow ! ( " \n \n \n " output status out err ) ) ; } if out . trim ( ) . starts_with ( " " ) { return Err ( anyhow ! ( " \n \n \n " out err ) ) ; } // Boogie output contains the string "errors detected in" whenever parsing, // resolution, or type checking errors are discovered. if out . contains ( " " ) { return Err ( anyhow ! ( " \n " out ) ) ; } if out . contains ( " " ) { return Err ( anyhow ! ( " \n " out ) ) ; } let mut errors = self . extract_verification_errors ( & out ) ; errors . extend ( self . extract_inconclusive_errors ( & out ) ) ; errors . extend ( self . extract_inconsistency_errors ( & out ) ) ; Ok ( BoogieOutput { errors , all_output : out , } ) }
Calls boogie on the given file.
Calls boogie on the given file .
&self
boogie_file
&str