use super::{Operator, Rule, Term};
use itertools::Itertools;
use rand::seq::sample_iter;
use rand::Rng;
use std::fmt;
#[derive(Debug, Hash, Clone, PartialEq, Eq)]
pub struct TRS {
pub(crate) is_deterministic: bool,
pub rules: Vec<Rule>,
}
impl TRS {
pub fn new(rules: Vec<Rule>) -> TRS {
TRS {
rules,
is_deterministic: false,
}
}
pub fn make_deterministic<R: Rng>(&mut self, rng: &mut R) -> bool {
if !self.is_deterministic {
self.rules = self
.rules
.iter()
.cloned()
.map(|r| {
let new_rhs = sample_iter(rng, r.rhs, 1).expect("sample_iter failed.");
Rule::new(r.lhs, new_rhs).expect("making new rule from old rule failed")
})
.collect();
self.is_deterministic = true;
true
} else {
false
}
}
pub fn make_nondeterministic(&mut self) -> bool {
let previous_state = self.is_deterministic;
self.is_deterministic = false;
previous_state
}
pub fn is_deterministic(&self) -> bool {
self.is_deterministic
}
pub fn len(&self) -> usize {
self.rules.len()
}
pub fn is_empty(&self) -> bool {
self.rules.is_empty()
}
pub fn size(&self) -> usize {
self.rules.iter().map(Rule::size).sum()
}
pub fn display(&self) -> String {
self.rules
.iter()
.map(|r| format!("{};", r.display()))
.join("\n")
}
pub fn pretty(&self) -> String {
self.rules
.iter()
.map(|r| format!("{};", r.pretty()))
.join("\n")
}
pub fn clauses(&self) -> Vec<Rule> {
self.rules.iter().flat_map(Rule::clauses).collect()
}
pub fn operators(&self) -> Vec<Operator> {
self.rules
.iter()
.flat_map(Rule::operators)
.unique()
.collect()
}
pub fn unifies(trs1: TRS, trs2: TRS) -> bool {
trs1.len() == trs2.len()
&& trs1
.rules
.iter()
.zip(trs2.rules.iter())
.all(|(r1, r2)| Rule::unify(r1, r2).is_some())
}
pub fn pmatches(trs1: TRS, trs2: TRS) -> bool {
trs1.len() == trs2.len()
&& trs1
.rules
.iter()
.zip(trs2.rules.iter())
.all(|(r1, r2)| Rule::pmatch(r1, r2).is_some())
}
pub fn alphas(trs1: &TRS, trs2: &TRS) -> bool {
TRS::pmatches(trs2.clone(), trs1.clone()) && TRS::pmatches(trs1.clone(), trs2.clone())
}
fn rewrite_head(&self, term: &Term) -> Option<Vec<Term>> {
for rule in &self.rules {
if let Some(ref sub) = Term::pmatch(vec![(&rule.lhs, &term)]) {
return Some(rule.rhs.iter().map(|x| x.substitute(sub)).collect());
}
}
None
}
fn rewrite_args(&self, term: &Term, strategy: Strategy) -> Option<Vec<Term>> {
if let Term::Application { ref op, ref args } = *term {
for (i, arg) in args.iter().enumerate() {
if let Some(v) = self.rewrite(arg, strategy) {
let res = v
.iter()
.map(|x| {
let mut args = args.clone();
args[i] = x.clone();
Term::Application {
op: op.clone(),
args,
}
})
.collect();
return Some(res);
}
}
None
} else {
None
}
}
fn rewrite_all(&self, term: &Term) -> Option<Vec<Term>> {
match term {
Term::Variable(_) => None,
Term::Application { ref args, .. } => {
let mut rewrites = self.rewrite_head(term).unwrap_or_else(|| vec![]);
for (i, arg) in args.iter().enumerate() {
for rewrite in self.rewrite_all(arg).unwrap_or_else(|| vec![]) {
rewrites.push(term.replace(&[i], rewrite).unwrap());
}
}
Some(rewrites)
}
}
}
pub fn rewrite(&self, term: &Term, strategy: Strategy) -> Option<Vec<Term>> {
match *term {
Term::Variable(_) => None,
ref app => match strategy {
Strategy::Normal => self
.rewrite_head(app)
.or_else(|| self.rewrite_args(app, strategy)),
Strategy::Eager => self
.rewrite_args(app, strategy)
.or_else(|| self.rewrite_head(app)),
Strategy::All => self.rewrite_all(app),
},
}
}
pub fn get(&self, lhs: &Term) -> Option<(usize, Rule)> {
for (idx, rule) in self.rules.iter().enumerate() {
if Term::alpha(lhs, &rule.lhs).is_some() {
return Some((idx, rule.clone()));
}
}
None
}
pub fn get_idx(&self, idx: usize) -> Option<Rule> {
if self.rules.len() > idx {
Some(self.rules[idx].clone())
} else {
None
}
}
pub fn get_clause(&self, rule: &Rule) -> Option<(usize, Rule)> {
for (i, r) in self.rules.iter().enumerate() {
if let Some(sub) = r.contains(rule) {
return Some((i, rule.substitute(&sub)));
}
}
None
}
pub fn remove(&mut self, lhs: &Term) -> Result<Rule, TRSError> {
if let Some((idx, _)) = self.get(lhs) {
Ok(self.rules.remove(idx))
} else {
Err(TRSError::NotInTRS)
}
}
pub fn remove_idx(&mut self, idx: usize) -> Result<Rule, TRSError> {
if self.rules.len() > idx {
Ok(self.rules.remove(idx))
} else {
Err(TRSError::InvalidIndex(idx, self.rules.len()))
}
}
pub fn remove_clauses(&mut self, rule: &Rule) -> Result<Rule, TRSError> {
self.rules
.iter_mut()
.filter_map(|r| r.discard(&rule))
.next()
.ok_or(TRSError::NotInTRS)
.and_then(|discarded| {
self.rules.retain(|rule| !rule.is_empty());
Ok(discarded)
})
}
pub fn insert(&mut self, idx: usize, rule: Rule) -> Result<&mut TRS, TRSError> {
if self.insert_clauses(&rule).is_err() {
self.insert_idx(idx, rule)
} else {
Ok(self)
}
}
pub fn insert_idx(&mut self, idx: usize, rule: Rule) -> Result<&mut TRS, TRSError> {
if self.is_deterministic && rule.len() > 1 {
return Err(TRSError::NondeterministicRule);
} else if idx > self.rules.len() {
return Err(TRSError::InvalidIndex(idx, self.rules.len()));
} else if self.get(&rule.lhs).is_some() {
return Err(TRSError::AlreadyInTRS);
}
self.rules.insert(idx, rule);
Ok(self)
}
pub fn inserts_idx(&mut self, idx: usize, rules: Vec<Rule>) -> Result<&mut TRS, TRSError> {
for rule in rules.into_iter().rev() {
self.insert_idx(idx, rule)?;
}
Ok(self)
}
pub fn insert_clauses(&mut self, rule: &Rule) -> Result<&mut TRS, TRSError> {
if self.is_deterministic {
Err(TRSError::NondeterministicRule)
} else if let Some((idx, _)) = self.get(&rule.lhs) {
self.rules[idx].merge(rule);
Ok(self)
} else {
Err(TRSError::NotInTRS)
}
}
pub fn push(&mut self, rule: Rule) -> Result<&mut TRS, TRSError> {
let lhs = rule.lhs.clone();
self.insert(0, rule)?
.get(&lhs)
.ok_or(TRSError::NotInTRS)
.and_then(move |(idx, _)| self.move_rule(idx, 0))
}
pub fn pushes(&mut self, rules: Vec<Rule>) -> Result<&mut TRS, TRSError> {
for rule in rules.into_iter().rev() {
self.push(rule)?;
}
Ok(self)
}
pub fn move_rule(&mut self, i: usize, j: usize) -> Result<&mut TRS, TRSError> {
if i != j {
let rule = self.remove_idx(i)?;
self.insert(j, rule)
} else {
Ok(self)
}
}
pub fn replace(&mut self, idx: usize, rule1: &Rule, rule2: Rule) -> Result<&mut TRS, TRSError> {
self.remove_clauses(rule1)?;
self.insert(idx, rule2)
}
}
#[derive(Debug, Copy, Clone)]
pub enum Strategy {
Normal,
Eager,
All,
}
impl fmt::Display for Strategy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Strategy::Normal => write!(f, "Normal"),
Strategy::Eager => write!(f, "Eager"),
Strategy::All => write!(f, "All"),
}
}
}
#[derive(Debug, Clone)]
pub enum TRSError {
NotInTRS,
AlreadyInTRS,
NondeterministicRule,
InvalidIndex(usize, usize),
}
impl fmt::Display for TRSError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
TRSError::NotInTRS => write!(f, "query rule not in TRS"),
TRSError::AlreadyInTRS => write!(f, "pre-existing rule with same LHS in TRS"),
TRSError::NondeterministicRule => {
write!(f, "proposed rule is nondeterministic in deterministic TRS")
}
TRSError::InvalidIndex(length, max_length) => {
write!(f, "index {} greater than max index {}", length, max_length)
}
}
}
}
impl ::std::error::Error for TRSError {
fn description(&self) -> &'static str {
"TRS error"
}
}
#[cfg(test)]
mod tests {
use super::super::super::parser::*;
use super::super::Signature;
use super::*;
#[test]
fn new_test() {
let mut sig = Signature::default();
let r0 = parse_rule(&mut sig, "A = B").expect("parse of A = B");
let r1 = parse_rule(&mut sig, "C(x_) = x_").expect("parse of C(x_) = x_");
let r2 = parse_rule(&mut sig, "D(y_) = D(E)").expect("parse of D(y_) = D(E)");
let new_trs = TRS::new(vec![r0, r1, r2]);
assert_eq!(new_trs.display(), "A = B;\nC(x_) = x_;\nD(y_) = D(E);");
}
#[test]
fn make_deterministic_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B | C;
D = E;",
)
.expect("parse of A = B | C; D = E");
let mut r = rand::thread_rng();
let str_before = t.display();
assert!(t.make_deterministic(&mut r));
assert_ne!(t.display(), str_before);
let str_before = t.display();
let r = parse_rule(&mut sig, "C = B | D").expect("parse of C = B | D");
if t.insert_idx(1, r.clone()).is_err() {
assert!(true);
}
assert_eq!(str_before, t.display());
assert!((t.display() == "A = B;\nD = E;") || (t.display() == "A = C;\nD = E;"));
}
#[test]
fn make_nondeterministic_test() {
let mut sig = Signature::default();
let mut t = parse_trs(&mut sig, "A = B | C; D = E;").expect("parse of A = B | C; D = E");
let mut r = rand::thread_rng();
t.make_deterministic(&mut r);
let str_before = t.display();
let r = parse_rule(&mut sig, "C = B | D").expect("parse of C = B | D");
assert!(t.insert_idx(1, r.clone()).is_err());
assert_eq!(str_before, t.display());
assert!(t.make_nondeterministic());
t.insert_idx(1, r).expect("inserting C = B | D");
assert!(
(t.display() == "A = B;\nC = B | D;\nD = E;")
|| (t.display() == "A = C;\nC = B | D;\nD = E;")
);
}
#[test]
fn is_deterministic_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B | C;
D = E;",
)
.expect("parse of A = B | C; D = E");
let mut r = rand::thread_rng();
assert!(!t.is_deterministic());
t.make_deterministic(&mut r);
assert!(t.is_deterministic());
}
#[test]
fn len_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
assert_eq!(t.len(), 3);
}
#[test]
fn is_empty_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
assert!(!t.is_empty());
let t = parse_trs(&mut sig, "").expect("parse of blank string");
assert!(t.is_empty());
}
#[test]
fn size_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
assert_eq!(t.size(), 8);
}
#[test]
fn display_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
assert_eq!(t.display(), "A = B;\nC = D | E;\nF(x_) = G;");
let trs = parse_trs(&mut sig,
"A(x_ y_ z_) = A(x_ DECC(DECC(DIGIT(1) 0) 5) SUCC(SUCC(ZERO))); CONS(B CONS(C CONS(D NIL))) = CONS(C CONS(D NIL)); B C D E = B C | D E;")
.expect("parse of A(x_ y_ z_) = A(x_ DECC(DECC(DIGIT(1) 0) 5) SUCC(SUCC(ZERO)));
CONS(B CONS(C CONS(D NIL))) = CONS(C CONS(D NIL));
B C D E = B C | D E;");
assert_eq!(trs.display(),
"A(x_ y_ z_) = A(x_ DECC(DECC(DIGIT(1) 0) 5) SUCC(SUCC(ZERO)));\nCONS(B CONS(C CONS(D NIL))) = CONS(C CONS(D NIL));\n.(.(.(B C) D) E) = .(B C) | .(D E);");
}
#[test]
fn pretty_test() {
let mut sig = Signature::default();
let trs = parse_trs(
&mut sig,
"A(x_ y_ z_) = A(x_ DECC(DECC(DIGIT(1) 0) 5) SUCC(SUCC(ZERO)));
CONS(B CONS(C CONS(D NIL))) = CONS(C CONS(D NIL));
B C D E = B C | D E;",
)
.expect(
"parse of A(x_ y_ z_) = A(x_ DECC(DECC(DIGIT(1) 0) 5) SUCC(SUCC(ZERO)));
CONS(B CONS(C CONS(D NIL))) = CONS(C CONS(D NIL));
B C D E = B C | D E;",
);
assert_eq!(
trs.pretty(),
"A(x_, y_, z_) = A(x_, 105, 2);\n[B, C, D] = [C, D];\nB C D E = B C | D E;"
);
}
#[test]
fn clauses_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F = G;",
)
.expect("parse of A = B; C = D | E; F = G;");
let r0 = parse_rule(&mut sig, "A = B").expect("parse of A = B");
let r1 = parse_rule(&mut sig, "C = D").expect("parse of C = D");
let r2 = parse_rule(&mut sig, "C = E").expect("parse of C = E");
let r3 = parse_rule(&mut sig, "F = G").expect("parse of F = G");
assert_eq!(t.clauses(), vec![r0, r1, r2, r3]);
}
#[test]
fn operators_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let ops: Vec<String> = t.operators().iter().map(|o| o.display()).collect();
assert_eq!(ops, vec!["A", "B", "C", "D", "E", "F", "G"]);
}
#[test]
fn unifies_test() {
let mut sig = Signature::default();
let t0 = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let t1 = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(H) = G;",
)
.expect("parse of A = B; C = D | E; F(H) = G;");
assert!(TRS::unifies(t0.clone(), t1));
let t2 = parse_trs(
&mut sig,
"B = A;
C = D | E;
F(y_) = G;",
)
.expect("parse of A = B; C = D | E; F(y_) = G;");
assert!(!TRS::unifies(t0, t2));
}
#[test]
fn pmatches() {
let mut sig = Signature::default();
let t0 = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let t1 = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(H) = G;",
)
.expect("parse of A = B; C = D | E; F(H) = G;");
assert!(TRS::pmatches(t0.clone(), t1));
let t2 = parse_trs(
&mut sig,
"B = A;
C = D | E;
F(y_) = G;",
)
.expect("parse of A = B; C = D | E; F(y_) = G;");
assert!(!TRS::pmatches(t0.clone(), t2));
let t3 = parse_trs(
&mut sig,
"A = B | C;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B | C; C = D | E; F(x_) = G");
assert!(TRS::pmatches(t0.clone(), t3));
let t4 = parse_trs(
&mut sig,
"A = B;
C = D;
D = E;",
)
.expect("parse of A = B; C = D; D = E;");
assert!(!TRS::pmatches(t0, t4));
}
#[test]
fn alphas_test() {
let mut sig = Signature::default();
let t0 = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let t1 = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(H) = G;",
)
.expect("parse of A = B; C = D | E; F(H) = G;");
assert!(!TRS::alphas(&t0, &t1));
let t2 = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(y_) = G;",
)
.expect("parse of A = B; C = D | E; F(y_) = G;");
assert!(TRS::alphas(&t0, &t2));
}
#[test]
fn rewrite_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let term = parse_term(&mut sig, "J(F(C) K(C A))").expect("parse of J(F(C) K(C A))");
let rewritten_terms = &t.rewrite(&term, Strategy::Normal).unwrap();
assert_eq!(rewritten_terms.len(), 1);
assert_eq!(rewritten_terms[0].display(), "J(G K(C A))");
let rewritten_terms = &t.rewrite(&term, Strategy::Eager).unwrap();
assert_eq!(rewritten_terms.len(), 2);
assert_eq!(rewritten_terms[0].display(), "J(F(D) K(C A))");
assert_eq!(rewritten_terms[1].display(), "J(F(E) K(C A))");
let rewritten_terms = &t.rewrite(&term, Strategy::All).unwrap();
assert_eq!(rewritten_terms.len(), 6);
assert_eq!(rewritten_terms[0].display(), "J(G K(C A))");
assert_eq!(rewritten_terms[1].display(), "J(F(D) K(C A))");
assert_eq!(rewritten_terms[2].display(), "J(F(E) K(C A))");
assert_eq!(rewritten_terms[3].display(), "J(F(C) K(D A))");
assert_eq!(rewritten_terms[4].display(), "J(F(C) K(E A))");
assert_eq!(rewritten_terms[5].display(), "J(F(C) K(C B))");
}
#[test]
fn get_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let a = parse_term(&mut sig, "A").expect("parse of A");
assert_eq!(t.get(&a).unwrap().1.display(), "A = B");
let c = parse_term(&mut sig, "C").expect("parse of C");
assert_eq!(t.get(&c).unwrap().1.display(), "C = D | E");
}
#[test]
fn get_idx_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
assert_eq!(t.get_idx(0).unwrap().display(), "A = B");
assert_eq!(t.get_idx(1).unwrap().display(), "C = D | E");
}
#[test]
fn get_clause_test() {
let mut sig = Signature::default();
let t = parse_trs(
&mut sig,
"A(a_ b_) = B(b_ b_);
D(c_ e_) = D(E F);",
)
.expect("parse of A(a_ b_) = B(b_ b_); D(c_ e_) = D(E F);");
let r = parse_rule(&mut sig, "A(x_ y_) = B(y_ y_)").expect("parse of A(x_ y_) = B(y_ y_)");
assert_eq!(t.get_clause(&r).unwrap().1.display(), "A(a_ b_) = B(b_ b_)");
let r = parse_rule(&mut sig, "D(w_ q_) = D(E F)").expect("parse of D(w_ q_) = D(E F)");
assert_eq!(t.get_clause(&r).unwrap().1.display(), "D(c_ e_) = D(E F)");
}
#[test]
fn remove_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let a = parse_term(&mut sig, "A").expect("parse of A");
let c = parse_term(&mut sig, "C").expect("parse of C");
assert_eq!(t.remove(&a).expect("removing A = B").display(), "A = B");
assert_eq!(t.remove(&c).expect("removing C = D").display(), "C = D | E");
assert_eq!(t.display(), "F(x_) = G;");
}
#[test]
fn remove_idx_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
assert_eq!(t.remove_idx(0).expect("removing A = B").display(), "A = B");
assert_eq!(
t.remove_idx(0).expect("removing C = D").display(),
"C = D | E"
);
assert_eq!(t.display(), "F(x_) = G;");
}
#[test]
fn remove_clauses_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let r = parse_rule(&mut sig, "C = D").expect("parse of C = D");
assert_eq!(
t.remove_clauses(&r).expect("removing C = D").display(),
"C = D"
);
assert_eq!(t.display(), "A = B;\nC = E;\nF(x_) = G;");
}
#[test]
fn insert_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let r = parse_rule(&mut sig, "D = G").expect("parse of D = G");
t.insert(1, r).expect("inserting D = G at index 1");
assert_eq!(t.display(), "A = B;\nD = G;\nC = D | E;\nF(x_) = G;");
let r = parse_rule(&mut sig, "D = A").expect("parse of D = A");
t.insert(0, r).expect("inserting D = A with D = G");
assert_eq!(t.display(), "A = B;\nD = G | A;\nC = D | E;\nF(x_) = G;");
}
#[test]
fn insert_idx_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let r = parse_rule(&mut sig, "D = G").expect("parse of D = G");
t.insert_idx(1, r).expect("inserting D = G at index 1");
assert_eq!(t.display(), "A = B;\nD = G;\nC = D | E;\nF(x_) = G;");
}
#[test]
fn inserts_idx_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = H;",
)
.expect("parse of A = B; C = D | E; F(x_) = H;");
let r0 = parse_rule(&mut sig, "G(y_) = y_").expect("parse of G(y_) = y_");
let r1 = parse_rule(&mut sig, "B = C").expect("parse of B = C");
let r2 = parse_rule(&mut sig, "E = F | B").expect("parse of E = F | B");
t.inserts_idx(2, vec![r0, r1, r2])
.expect("inserting 3 rules at index 2");
assert_eq!(
t.display(),
"A = B;\nC = D | E;\nG(y_) = y_;\nB = C;\nE = F | B;\nF(x_) = H;"
);
}
#[test]
fn insert_clauses_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let r = parse_rule(&mut sig, "A = H").expect("parse of A = H");
let t = t.insert_clauses(&r).expect("inserting A = H with A = B");
assert_eq!(t.display(), "A = B | H;\nC = D | E;\nF(x_) = G;");
}
#[test]
fn push_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let r = parse_rule(&mut sig, "G(y_) = y_").expect("parse of G(y_) = y_");
t.push(r).expect("inserting G(y_) = y_ at index 0");
assert_eq!(t.display(), "G(y_) = y_;\nA = B;\nC = D | E;\nF(x_) = G;");
}
#[test]
fn pushes_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = H;",
)
.expect("parse of A = B; C = D | E; F(x_) = H;");
let r0 = parse_rule(&mut sig, "G(y_) = y_").expect("parse of G(y_) = y_");
let r1 = parse_rule(&mut sig, "B = C").expect("parse of B = C");
let r2 = parse_rule(&mut sig, "E = F | B").expect("parse of E = F | B");
t.pushes(vec![r0, r1, r2])
.expect("inserting 3 rules at index 0");
assert_eq!(
t.display(),
"G(y_) = y_;\nB = C;\nE = F | B;\nA = B;\nC = D | E;\nF(x_) = H;"
);
}
#[test]
fn move_rule_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;
H = I;",
)
.expect("parse of A = B; C = D | E; F(x_) = G; H = I;");
t.move_rule(0, 2)
.expect("moving rule from index 0 to index 2");
assert_eq!(t.display(), "C = D | E;\nF(x_) = G;\nA = B;\nH = I;");
}
#[test]
fn replace_test() {
let mut sig = Signature::default();
let mut t = parse_trs(
&mut sig,
"A = B;
C = D | E;
F(x_) = G;",
)
.expect("parse of A = B; C = D | E; F(x_) = G;");
let r = parse_rule(&mut sig, "C = D").expect("parse of C = D");
let r_new = parse_rule(&mut sig, "C = A").expect("parse of C = A");
t.replace(0, &r, r_new)
.expect("replaceing C = D with C = A");
assert_eq!(t.display(), "A = B;\nC = E | A;\nF(x_) = G;");
}
}