use std::fmt::Display;
use num_traits::One;
use crate::prelude::*;
type LitData = usize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
pub struct Lit {
data: LitData,
}
impl Lit {
#[inline]
pub fn from_raw_data(data: usize) -> Self {
Lit { data }
}
#[inline]
pub fn new_undef() -> Self {
Lit { data: usize::MAX }
}
#[inline]
pub fn is_undef(&self) -> bool {
self.data == usize::MAX
}
#[inline]
pub fn from_var(var_idx: VarIdx, is_negated: bool) -> Self {
Lit {
data: (var_idx << 1) ^ (is_negated as usize),
}
}
#[inline]
pub fn is_negated(&self) -> bool {
self.data % 2 == 1
}
#[inline]
pub fn negate(&mut self) {
self.data ^= 1;
}
#[inline]
pub fn get_var(&self) -> VarIdx {
self.data >> 1
}
#[inline]
pub fn get_lit_data(&self) -> LitData {
self.data
}
}
impl PBTerm for Lit {
type CoeffType = i64;
#[inline]
fn negate(&mut self) {
self.negate();
}
#[inline]
fn get_lit(&self) -> Lit {
*self
}
#[inline]
fn get_coeff(&self) -> &i64 {
&1
}
#[inline]
fn set_coeff(&mut self, coeff: Self::CoeffType) {
if !coeff.is_one() {
panic!("Trying to set coefficient for Clause or Cardinality to something else than 1!")
}
}
#[inline]
fn divide_round_up(&mut self, _divisor: &Self::CoeffType) {}
}
impl Display for Lit {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.data)
}
}
impl std::ops::Neg for Lit {
type Output = Lit;
#[inline]
fn neg(mut self) -> Self::Output {
self.negate();
self
}
}
impl ToPrettyString for Lit {
#[inline]
fn to_pretty_string(&self, var_names: &VarNameManager) -> String {
if self.is_negated() {
"~".to_string() + var_names.get_name(self.get_var())
} else {
var_names.get_name(self.get_var()).to_string()
}
}
}