logicrs 0.6.1

Rust library for logic expression
Documentation
use super::{Sort, Term, TermType, TermVec};
use crate::{DagCnf, Lit};
use giputils::{bitvec::BitVec, hash::GHashMap};
use std::{iter::repeat_with, ops::Deref};

#[inline]
fn bv_const_bitblast(c: &BitVec) -> TermVec {
    c.iter().map(Term::bool_const).collect()
}

#[inline]
fn bv_const_cnf_encode(c: &BitVec) -> Lit {
    debug_assert!(c.len() == 1);
    Lit::constant(c.get(0))
}

pub fn var_bitblast(sort: Sort) -> TermVec {
    let size = sort.size();
    repeat_with(|| Term::new_var(Sort::bool()))
        .take(size)
        .collect()
}

impl Term {
    pub fn bitblast(&self, map: &mut GHashMap<Term, TermVec>) -> TermVec {
        if let Some(res) = map.get(self) {
            return res.clone();
        }
        let blast = match self.deref() {
            TermType::Const(const_term) => bv_const_bitblast(const_term),
            TermType::Var(_) => var_bitblast(self.sort()),
            TermType::Op(op_term) => {
                let terms: Vec<TermVec> = op_term.terms.iter().map(|s| s.bitblast(map)).collect();
                op_term.op.bitblast(&terms)
            }
        };
        map.insert(self.clone(), blast.clone());
        map.get(self).unwrap().clone()
    }

    pub fn cnf_encode(&self, dc: &mut DagCnf, map: &mut GHashMap<Term, Lit>) -> Lit {
        if let Some(res) = map.get(self) {
            return *res;
        }
        let blast = match self.deref() {
            TermType::Const(const_term) => bv_const_cnf_encode(const_term),
            TermType::Var(_) => dc.new_var().lit(),
            TermType::Op(op_term) => {
                let terms: Vec<Lit> = op_term
                    .terms
                    .iter()
                    .map(|s| s.cnf_encode(dc, map))
                    .collect();
                op_term.op.cnf_encode(dc, &terms)
            }
        };
        map.insert(self.clone(), blast);
        *map.get(self).unwrap()
    }
}

pub fn bitblast_terms<I: IntoIterator<Item = impl AsRef<Term>>>(
    terms: I,
    map: &mut GHashMap<Term, TermVec>,
) -> impl Iterator<Item = TermVec> {
    terms.into_iter().map(|t| t.as_ref().bitblast(map))
}

pub fn cnf_encode_terms<I: IntoIterator<Item = impl AsRef<Term>>>(
    terms: I,
    dc: &mut DagCnf,
    map: &mut GHashMap<Term, Lit>,
) -> impl Iterator<Item = Lit> {
    terms.into_iter().map(|t| t.as_ref().cnf_encode(dc, map))
}