veripb_formula/
assignment.rs1use std::fmt::Display;
4
5use crate::prelude::*;
6
7#[derive(Debug, Default, Clone)]
9pub struct Assignment<V> {
10 pub assignment: Vec<V>,
11}
12
13impl<V> Assignment<V>
14where
15 V: VarType,
16{
17 #[inline]
19 pub fn with_size(size: usize) -> Self {
20 Assignment::<V> {
21 assignment: vec![Default::default(); size],
22 }
23 }
24
25 #[inline]
29 pub fn resize(&mut self, new_len: usize) {
30 self.assignment.resize(new_len, Default::default());
31 }
32
33 #[inline]
35 pub fn set_value(&mut self, idx: VarIdx, value: V::Value) {
36 self.assignment[idx].set_value(value);
37 }
38
39 #[inline]
41 pub fn get_value(&self, idx: VarIdx) -> V::Value {
42 self.assignment[idx].get_value()
43 }
44
45 #[inline]
47 pub fn set_lit_value(&mut self, lit: Lit, value: V::Value) {
48 if lit.is_negated() {
49 self.assignment[lit.get_var()].set_value(value.negate());
50 } else {
51 self.assignment[lit.get_var()].set_value(value);
52 }
53 }
54
55 #[inline]
63 pub unsafe fn set_lit_value_unchecked(&mut self, lit: Lit, value: V::Value) {
64 debug_assert!(lit.get_var() < self.assignment.len());
65 if lit.is_negated() {
66 self.assignment
67 .get_unchecked_mut(lit.get_var())
68 .set_value(value.negate());
69 } else {
70 self.assignment
71 .get_unchecked_mut(lit.get_var())
72 .set_value(value);
73 }
74 }
75
76 #[inline]
78 pub fn get_lit_value(&self, lit: Lit) -> V::Value {
79 if let Some(value) = self.assignment.get(lit.get_var()) {
80 if lit.is_negated() {
81 value.get_value().negate()
82 } else {
83 value.get_value()
84 }
85 } else {
86 V::Value::default()
87 }
88 }
89
90 #[inline]
98 pub unsafe fn get_lit_value_unchecked(&self, lit: Lit) -> V::Value {
99 debug_assert!(lit.get_var() < self.assignment.len());
100 let value = self.assignment.get_unchecked(lit.get_var()).get_value();
101 if lit.is_negated() {
102 value.negate()
103 } else {
104 value
105 }
106 }
107
108 #[inline]
110 pub fn reset(&mut self) {
111 self.assignment.fill(Default::default());
112 }
113
114 #[inline]
116 pub fn len(&self) -> usize {
117 self.assignment.len()
118 }
119
120 #[inline]
122 pub fn is_empty(&self) -> bool {
123 self.assignment.is_empty()
124 }
125}
126
127impl Assignment<BooleanVar> {
128 #[inline]
132 pub fn from(literals: &Vec<Lit>) -> Option<Self> {
133 let mut assignment = Assignment::with_size(literals.len());
134 for &lit in literals {
135 if lit.get_var() >= assignment.len() {
136 assignment.resize(2 * lit.get_var());
137 }
138 if unsafe { assignment.get_lit_value_unchecked(lit) } == BoolValue::Assigned(false) {
139 return None;
140 }
141 unsafe { assignment.set_lit_value_unchecked(lit, BoolValue::Assigned(true)) };
142 }
143 Some(assignment)
144 }
145
146 #[inline]
150 pub fn is_unassigned(&self, var: VarIdx) -> bool {
151 matches!(self.assignment[var].get_value(), BoolValue::Unassigned)
152 }
153
154 #[inline]
158 pub fn is_assigned(&self, var: VarIdx) -> bool {
159 matches!(self.assignment[var].get_value(), BoolValue::Assigned(_))
160 }
161}
162
163impl ToPrettyString for Assignment<BooleanVar> {
164 fn to_pretty_string(&self, var_names: &VarNameManager) -> String {
165 let mut output = String::with_capacity(8 * self.len());
166 for (idx, var) in self.assignment.iter().enumerate() {
167 match var.get_value() {
168 BoolValue::Assigned(true) => {
169 output.push_str(var_names.get_name(idx));
170 output.push(' ');
171 }
172 BoolValue::Assigned(false) => {
173 output.push('~');
174 output.push_str(var_names.get_name(idx));
175 output.push(' ');
176 }
177 BoolValue::Unassigned => {}
178 }
179 }
180 output.pop();
181 output
182 }
183}
184
185impl Display for Assignment<BooleanVar> {
186 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
187 for (idx, var) in self.assignment.iter().enumerate() {
188 match var.get_value() {
189 BoolValue::Unassigned => writeln!(f, "{}: -", idx + 1)?,
190 BoolValue::Assigned(val) => writeln!(f, "{}: {}", idx + 1, val)?,
191 }
192 }
193 Ok(())
194 }
195}