use crate::types::*;
pub struct RuleSet {
rules: Vec<Rule>,
}
impl RuleSet {
pub fn new() -> Self {
Self {
rules: Self::build_rules(),
}
}
fn build_rules() -> Vec<Rule> {
vec![
Rule {
name: "use_after_free".to_string(),
head: Predicate::UseAfterFree {
var: "X".to_string(),
use_loc: 0,
free_loc: 0,
},
body: vec![
Predicate::Fact(Fact::Free {
var: "X".to_string(),
location: 0,
}),
Predicate::Fact(Fact::Use {
var: "X".to_string(),
location: 0,
}),
],
},
Rule {
name: "double_free".to_string(),
head: Predicate::DoubleFree {
var: "X".to_string(),
loc1: 0,
loc2: 0,
},
body: vec![
Predicate::Fact(Fact::Free {
var: "X".to_string(),
location: 0,
}),
Predicate::Fact(Fact::Free {
var: "X".to_string(),
location: 0,
}),
],
},
Rule {
name: "deadlock".to_string(),
head: Predicate::Deadlock {
m1: "M1".to_string(),
m2: "M2".to_string(),
},
body: vec![
Predicate::Fact(Fact::Lock {
mutex: "M1".to_string(),
location: 0,
}),
Predicate::Fact(Fact::Lock {
mutex: "M2".to_string(),
location: 0,
}),
],
},
Rule {
name: "data_race".to_string(),
head: Predicate::DataRace {
var: "X".to_string(),
loc1: 0,
loc2: 0,
},
body: vec![
Predicate::Fact(Fact::Write {
var: "X".to_string(),
location: 0,
}),
Predicate::Fact(Fact::Read {
var: "X".to_string(),
location: 0,
}),
],
},
]
}
pub fn rules(&self) -> &[Rule] {
&self.rules
}
}
impl Default for RuleSet {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ruleset_creation() {
let ruleset = RuleSet::new();
assert!(!ruleset.rules().is_empty());
assert!(ruleset.rules().len() >= 4);
}
#[test]
fn test_rule_names() {
let ruleset = RuleSet::new();
let names: Vec<_> = ruleset.rules().iter().map(|r| &r.name).collect();
assert!(names.contains(&&"use_after_free".to_string()));
assert!(names.contains(&&"double_free".to_string()));
assert!(names.contains(&&"deadlock".to_string()));
assert!(names.contains(&&"data_race".to_string()));
}
}