Path: blob/main/cranelift/isle/veri/veri_engine/src/verify.rs
1693 views
use crate::type_inference::type_rules_with_term_and_types;1use crate::Config;2use cranelift_isle::error::Errors;3use cranelift_isle::{self as isle};4use isle::compile::create_envs;5use isle::sema::{Pattern, RuleId, TermEnv, TypeEnv};6use std::collections::HashMap;7use std::path::PathBuf;89use crate::annotations::parse_annotations;10use crate::solver::run_solver;11use crate::type_inference::RuleSemantics;12use crate::{interp::Context, termname::pattern_contains_termname};13use veri_ir::{ConcreteTest, TermSignature, VerificationResult};1415pub fn verify_rules(16inputs: Vec<PathBuf>,17config: &Config,18widths: &Option<Vec<String>>,19) -> Result<(), Errors> {20// Produces environments including terms, rules, and maps from symbols and21// names to types22let (typeenv, termenv, defs) = create_envs(inputs).unwrap();2324let annotation_env = parse_annotations(&defs, &termenv, &typeenv);2526// Get the types/widths for this particular term27let types = annotation_env28.get_term_signatures_by_name(&termenv, &typeenv)29.get(&config.term as &str)30.unwrap_or_else(|| panic!("Missing term type instantiation for {}", config.term))31.clone();3233let types_filtered = if let Some(widths) = widths {34let mut width_types = Vec::new();3536for w in widths {37let width_type = match w.as_str() {38"I8" => veri_ir::Type::BitVector(Some(8)),39"I16" => veri_ir::Type::BitVector(Some(16)),40"I32" => veri_ir::Type::BitVector(Some(32)),41"I64" => veri_ir::Type::BitVector(Some(64)),42_ => panic!("Invalid width type: {w}"),43};44width_types.push(width_type);45}4647types48.into_iter()49.filter(|t| {50if let Some(canonical_type) = &t.canonical_type {51width_types.contains(canonical_type)52} else {53false54}55})56.collect::<Vec<_>>()57} else {58types59};6061for type_instantiation in types_filtered {62let type_sols = type_rules_with_term_and_types(63&termenv,64&typeenv,65&annotation_env,66config,67&type_instantiation,68&None,69);70verify_rules_for_term(71&termenv,72&typeenv,73&type_sols,74type_instantiation,75&None,76config,77);78}79Ok(())80}8182pub fn verify_rules_for_term(83termenv: &TermEnv,84typeenv: &TypeEnv,85typesols: &HashMap<RuleId, RuleSemantics>,86types: TermSignature,87concrete: &Option<ConcreteTest>,88config: &Config,89) -> VerificationResult {90let mut rules_checked = 0;91for rule in &termenv.rules {92// Only type rules with the given term on the LHS93if !pattern_contains_termname(94// Hack for now: typeid not used95&Pattern::Term(96cranelift_isle::sema::TypeId(0),97rule.root_term,98rule.args.clone(),99),100&config.term,101termenv,102typeenv,103) {104continue;105}106if let Some(names) = &config.names {107if rule.name.is_none() {108continue;109}110let name = &typeenv.syms[rule.name.unwrap().index()];111if !names.contains(name) {112continue;113} else {114log::debug!("Verifying rule: {name}");115}116}117let ctx = Context::new(typesols);118if ctx.typesols.get(&rule.id).is_none() {119continue;120}121let rule_sem = &ctx.typesols[&rule.id];122log::debug!("Term: {}", config.term);123log::debug!("Type instantiation: {types}");124let result = run_solver(rule_sem, rule, termenv, typeenv, concrete, config, &types);125rules_checked += 1;126if result != VerificationResult::Success {127return result;128}129}130if rules_checked > 0 {131VerificationResult::Success132} else {133panic!("No rules checked!")134}135}136137138