1#![cfg_attr(docsrs, feature(doc_cfg))]
4use std::cell::RefCell;
64use std::fmt::Debug;
65use std::ops::Neg;
66use std::rc::Rc;
67
68use generic_array::*;
69
70use crate::boolexpr::{bool_ite, bool_opt_ite, half_adder, BoolEqual, BoolExprNode, BoolImpl};
71pub use crate::boolexpr_creator::{ExprCreator, ExprCreator32, ExprCreatorSys};
72use crate::int_utils::*;
73pub use crate::intexpr::{
74 BitVal, DivMod, ExtraOps, FullMul, IntCondAdd, IntCondMul, IntCondNeg, IntCondShl, IntCondShr,
75 IntCondSub, IntEqual, IntError, IntExprNode, IntModAdd, IntModAddAssign, IntModMul,
76 IntModMulAssign, IntModNeg, IntModSub, IntModSubAssign, IntOrd, IntRol, IntRor,
77};
78use crate::writer::{Literal, VarLit};
79use crate::{impl_int_ipty, impl_int_upty};
80
81pub mod arith;
82pub use arith::*;
83
84pub mod extra_arith;
85pub use extra_arith::*;
86
87#[derive(Clone, Debug, PartialEq, Eq)]
99pub struct DynIntExprNode<T: VarLit + Debug, const SIGN: bool> {
100 pub(super) creator: Rc<RefCell<ExprCreator<T>>>,
101 pub(super) indexes: Vec<usize>,
102}
103
104impl<T, const SIGN: bool> DynIntExprNode<T, SIGN>
105where
106 T: VarLit + Neg<Output = T> + Debug,
107 isize: TryFrom<T>,
108 <T as TryInto<usize>>::Error: Debug,
109 <T as TryFrom<usize>>::Error: Debug,
110 <isize as TryFrom<T>>::Error: Debug,
111{
112 pub const SIGN: bool = SIGN;
114
115 pub fn variable(creator: Rc<RefCell<ExprCreator<T>>>, n: usize) -> Self {
117 let indexes = {
118 let mut creator = creator.borrow_mut();
119 (0..n)
120 .into_iter()
121 .map(|_| {
122 let l = creator.new_variable();
123 creator.single(l)
124 })
125 .collect::<Vec<_>>()
126 };
127 DynIntExprNode { creator, indexes }
128 }
129
130 pub fn from_boolexprs(iter: impl IntoIterator<Item = BoolExprNode<T>>) -> Self {
133 let mut creator = None;
134 let indexes = iter
135 .into_iter()
136 .map(|x| {
137 if let Some(c) = creator.clone() {
139 assert_eq!(Rc::as_ptr(&c), Rc::as_ptr(&x.creator));
140 } else {
141 creator = Some(x.creator.clone());
142 }
143 x.index
144 })
145 .collect::<Vec<_>>();
146 DynIntExprNode {
147 creator: creator.unwrap(),
148 indexes,
149 }
150 }
151
152 pub fn filled(
154 creator: Rc<RefCell<ExprCreator<T>>>,
155 n: usize,
156 v: impl Into<Literal<T>>,
157 ) -> Self {
158 DynIntExprNode {
159 creator: creator.clone(),
160 indexes: vec![creator.borrow_mut().single(v); n],
161 }
162 }
163
164 pub fn filled_expr(n: usize, v: BoolExprNode<T>) -> Self {
166 DynIntExprNode {
167 creator: v.creator.clone(),
168 indexes: vec![v.index; n],
169 }
170 }
171
172 pub fn as_unsigned(self) -> DynIntExprNode<T, false> {
174 DynIntExprNode {
175 creator: self.creator,
176 indexes: self.indexes,
177 }
178 }
179
180 pub fn as_signed(self) -> DynIntExprNode<T, true> {
182 DynIntExprNode {
183 creator: self.creator,
184 indexes: self.indexes,
185 }
186 }
187
188 #[inline]
190 pub fn len(&self) -> usize {
191 self.indexes.len()
192 }
193
194 #[inline]
196 pub fn is_empty(&self) -> bool {
197 self.indexes.is_empty()
198 }
199}
200
201impl<T> DynIntExprNode<T, false>
202where
203 T: VarLit + Neg<Output = T> + Debug,
204 isize: TryFrom<T>,
205 <T as TryInto<usize>>::Error: Debug,
206 <T as TryFrom<usize>>::Error: Debug,
207 <isize as TryFrom<T>>::Error: Debug,
208{
209 pub fn subvalue(&self, start: usize, n: usize) -> Self {
211 DynIntExprNode {
212 creator: self.creator.clone(),
213 indexes: Vec::from(&self.indexes[start..start + n]),
214 }
215 }
216
217 pub fn subvalues(&self, start: usize, ns: impl IntoIterator<Item = usize>) -> Vec<Self> {
219 let mut startx = start;
220 let mut out = vec![];
221 for n in ns.into_iter() {
222 out.push(self.subvalue(startx, n));
223 startx += n;
224 }
225 out
226 }
227
228 pub fn select_bits(&self, iter: impl IntoIterator<Item = usize>) -> Self {
231 DynIntExprNode {
232 creator: self.creator.clone(),
233 indexes: iter
234 .into_iter()
235 .map(|x| self.indexes[x])
236 .collect::<Vec<_>>(),
237 }
238 }
239
240 pub fn concat(self, rest: Self) -> Self {
242 assert_eq!(Rc::as_ptr(&self.creator), Rc::as_ptr(&rest.creator));
243 DynIntExprNode {
244 creator: self.creator.clone(),
245 indexes: self
246 .indexes
247 .into_iter()
248 .chain(rest.indexes.into_iter())
249 .collect::<Vec<_>>(),
250 }
251 }
252
253 pub fn split(self, k: usize) -> (Self, Self) {
255 (
256 DynIntExprNode {
257 creator: self.creator.clone(),
258 indexes: Vec::from(&self.indexes[0..k]),
259 },
260 DynIntExprNode {
261 creator: self.creator.clone(),
262 indexes: Vec::from(&self.indexes[k..]),
263 },
264 )
265 }
266}
267
268pub trait TryFromNSized<T>: Sized {
270 type Error;
271
272 fn try_from_n(input: T, n: usize) -> Result<Self, Self::Error>;
275}
276
277impl<T: VarLit> TryFromNSized<DynIntExprNode<T, false>> for DynIntExprNode<T, false> {
278 type Error = IntError;
279
280 fn try_from_n(input: DynIntExprNode<T, false>, n: usize) -> Result<Self, IntError> {
281 if n < input.indexes.len() {
282 if !input.indexes.iter().skip(n).all(|x| *x == 0) {
283 return Err(IntError::BitOverflow);
284 }
285 Ok(DynIntExprNode {
286 creator: input.creator,
287 indexes: Vec::from(&input.indexes[0..n]),
288 })
289 } else {
290 let mut indexes = Vec::from(input.indexes.as_slice());
291 indexes.resize(n, 0);
292 Ok(DynIntExprNode {
293 creator: input.creator,
294 indexes,
295 })
296 }
297 }
298}
299
300impl<T: VarLit> TryFromNSized<DynIntExprNode<T, true>> for DynIntExprNode<T, false> {
301 type Error = IntError;
302
303 fn try_from_n(input: DynIntExprNode<T, true>, n: usize) -> Result<Self, IntError> {
304 if n < input.indexes.len() {
305 if !input.indexes.iter().skip(n).all(|x| *x == 0) {
306 return Err(IntError::BitOverflow);
307 }
308 Ok(DynIntExprNode {
309 creator: input.creator,
310 indexes: Vec::from(&input.indexes[0..n]),
311 })
312 } else {
313 if *input.indexes.last().unwrap() != 0 {
314 return Err(IntError::CanBeNegative);
315 }
316 let mut indexes = Vec::from(input.indexes.as_slice());
317 indexes.resize(n, 0);
318 Ok(DynIntExprNode {
319 creator: input.creator,
320 indexes,
321 })
322 }
323 }
324}
325
326impl<T: VarLit> TryFromNSized<DynIntExprNode<T, false>> for DynIntExprNode<T, true> {
327 type Error = IntError;
328
329 fn try_from_n(input: DynIntExprNode<T, false>, n: usize) -> Result<Self, IntError> {
330 if n <= input.indexes.len() {
331 if !input.indexes.iter().skip(n - 1).all(|x| *x == 0) {
332 return Err(IntError::BitOverflow);
333 }
334 Ok(DynIntExprNode {
335 creator: input.creator,
336 indexes: Vec::from(&input.indexes[0..n]),
337 })
338 } else {
339 let mut indexes = Vec::from(input.indexes.as_slice());
340 indexes.resize(n, 0);
341 Ok(DynIntExprNode {
342 creator: input.creator,
343 indexes,
344 })
345 }
346 }
347}
348
349impl<T: VarLit> TryFromNSized<DynIntExprNode<T, true>> for DynIntExprNode<T, true> {
350 type Error = IntError;
351
352 fn try_from_n(input: DynIntExprNode<T, true>, n: usize) -> Result<Self, IntError> {
353 if n < input.indexes.len() {
354 let last_idx = input.indexes[n - 1];
355 if !input.indexes.iter().skip(n).all(|x| last_idx == *x) {
356 return Err(IntError::BitOverflow);
357 }
358 Ok(DynIntExprNode {
359 creator: input.creator,
360 indexes: Vec::from(&input.indexes[0..n]),
361 })
362 } else {
363 let last = *input.indexes.last().unwrap();
364 let mut indexes = Vec::from(input.indexes.as_slice());
365 indexes.resize(n, last);
366 Ok(DynIntExprNode {
367 creator: input.creator,
368 indexes,
369 })
370 }
371 }
372}
373
374impl<T, N, const SIGN: bool> From<IntExprNode<T, N, SIGN>> for DynIntExprNode<T, SIGN>
375where
376 T: VarLit,
377 N: ArrayLength<usize>,
378{
379 fn from(v: IntExprNode<T, N, SIGN>) -> Self {
380 DynIntExprNode {
381 creator: v.creator,
382 indexes: Vec::from(v.indexes.as_slice()),
383 }
384 }
385}
386
387impl<T: VarLit, const SIGN: bool> TryFromNSized<BoolExprNode<T>> for DynIntExprNode<T, SIGN>
388where
389 T: VarLit + Neg<Output = T> + Debug,
390 isize: TryFrom<T>,
391 <T as TryInto<usize>>::Error: Debug,
392 <T as TryFrom<usize>>::Error: Debug,
393 <isize as TryFrom<T>>::Error: Debug,
394{
395 type Error = IntError;
396
397 fn try_from_n(v: BoolExprNode<T>, n: usize) -> Result<Self, Self::Error> {
399 let ec = v.creator.clone();
400 if n > 0 {
401 Ok(Self::from_boolexprs(std::iter::once(v).chain(
402 (0..n - 1).map(|_| BoolExprNode::single_value(ec.clone(), false)),
403 )))
404 } else {
405 Err(IntError::BitOverflow)
406 }
407 }
408}
409
410pub trait TryIntConstantN<T: VarLit, U>: Sized {
413 fn try_constant_n(
416 creator: Rc<RefCell<ExprCreator<T>>>,
417 n: usize,
418 v: U,
419 ) -> Result<Self, IntError>;
420}
421
422macro_rules! impl_int_try_uconstant_n {
423 ($pty:ty) => {
424 impl<T: VarLit> TryIntConstantN<T, $pty> for DynIntExprNode<T, false> {
425 fn try_constant_n(
426 creator: Rc<RefCell<ExprCreator<T>>>,
427 n: usize,
428 v: $pty,
429 ) -> Result<Self, IntError> {
430 let bits = <$pty>::BITS as usize;
431 if n < bits && (v & ((((1 as $pty) << (bits - n)).overflowing_sub(1).0) << n)) != 0
433 {
434 return Err(IntError::BitOverflow);
435 }
436 Ok(DynIntExprNode {
437 creator,
438 indexes: (0..n)
439 .into_iter()
440 .map(|x| {
441 if x < bits {
443 usize::from((v & (1 << x)) != 0)
444 } else {
445 0
446 }
447 })
448 .collect::<Vec<_>>(),
449 })
450 }
451 }
452 };
453}
454
455impl_int_upty!(impl_int_try_uconstant_n);
456
457macro_rules! impl_int_try_iconstant_n {
458 ($pty:ty) => {
459 impl<T: VarLit> TryIntConstantN<T, $pty> for DynIntExprNode<T, true> {
460 fn try_constant_n(
461 creator: Rc<RefCell<ExprCreator<T>>>,
462 n: usize,
463 v: $pty,
464 ) -> Result<Self, IntError> {
465 let bits = <$pty>::BITS as usize;
466 if n < bits {
467 let mask = ((((1 as $pty) << (bits - n)).overflowing_sub(1).0) << n);
470 let signmask = if v < 0 { mask } else { 0 };
471 if (v & mask) != signmask {
472 return Err(IntError::BitOverflow);
473 }
474 }
475 Ok(DynIntExprNode {
476 creator,
477 indexes: (0..n)
478 .into_iter()
479 .map(|x| {
480 if x < bits {
482 usize::from((v & (1 << x)) != 0)
483 } else {
484 usize::from((v & (1 << ((<$pty>::BITS - 1) as usize))) != 0)
485 }
486 })
487 .collect::<Vec<_>>(),
488 })
489 }
490 }
491 };
492}
493
494impl_int_ipty!(impl_int_try_iconstant_n);
495
496impl<'a, T, const SIGN: bool> BitVal for &'a DynIntExprNode<T, SIGN>
497where
498 T: VarLit + Neg<Output = T> + Debug,
499 isize: TryFrom<T>,
500 <T as TryInto<usize>>::Error: Debug,
501 <T as TryFrom<usize>>::Error: Debug,
502 <isize as TryFrom<T>>::Error: Debug,
503{
504 type Output = BoolExprNode<T>;
505
506 fn bitnum(self) -> usize {
507 self.indexes.len()
508 }
509
510 fn bit(self, x: usize) -> Self::Output {
511 BoolExprNode::new(self.creator.clone(), self.indexes[x])
512 }
513}
514
515impl<T, const SIGN: bool> IntEqual for DynIntExprNode<T, SIGN>
519where
520 T: VarLit + Neg<Output = T> + Debug,
521 isize: TryFrom<T>,
522 <T as TryInto<usize>>::Error: Debug,
523 <T as TryFrom<usize>>::Error: Debug,
524 <isize as TryFrom<T>>::Error: Debug,
525{
526 type Output = BoolExprNode<T>;
527
528 fn equal(self, rhs: Self) -> Self::Output {
529 assert_eq!(self.indexes.len(), rhs.indexes.len());
530 let mut xp = BoolExprNode::single(self.creator.clone(), true);
531 for i in 0..self.indexes.len() {
532 xp &= self.bit(i).bequal(rhs.bit(i));
533 }
534 xp
535 }
536
537 fn nequal(self, rhs: Self) -> Self::Output {
538 assert_eq!(self.indexes.len(), rhs.indexes.len());
539 let mut xp = BoolExprNode::single(self.creator.clone(), false);
540 for i in 0..self.indexes.len() {
541 xp |= self.bit(i) ^ rhs.bit(i);
542 }
543 xp
544 }
545}
546
547impl<T> IntOrd for DynIntExprNode<T, false>
548where
549 T: VarLit + Neg<Output = T> + Debug,
550 isize: TryFrom<T>,
551 <T as TryInto<usize>>::Error: Debug,
552 <T as TryFrom<usize>>::Error: Debug,
553 <isize as TryFrom<T>>::Error: Debug,
554{
555 type Output = BoolExprNode<T>;
556
557 fn less_than(self, rhs: Self) -> Self::Output {
558 assert_eq!(self.indexes.len(), rhs.indexes.len());
559 let mut xp = (!self.bit(0)) & rhs.bit(0);
560 for i in 1..self.indexes.len() {
561 xp = (self.bit(i).bequal(rhs.bit(i)) & xp) | ((!self.bit(i)) & rhs.bit(i));
562 }
563 xp
564 }
565
566 fn less_equal(self, rhs: Self) -> Self::Output {
567 assert_eq!(self.indexes.len(), rhs.indexes.len());
568 let mut xp = self.bit(0).imp(rhs.bit(0));
569 for i in 1..self.indexes.len() {
570 xp = (self.bit(i).bequal(rhs.bit(i)) & xp) | ((!self.bit(i)) & rhs.bit(i));
571 }
572 xp
573 }
574
575 fn greater_than(self, rhs: Self) -> Self::Output {
576 rhs.less_than(self)
577 }
578
579 fn greater_equal(self, rhs: Self) -> Self::Output {
580 rhs.less_equal(self)
581 }
582}
583
584impl<T> IntOrd for DynIntExprNode<T, true>
585where
586 T: VarLit + Neg<Output = T> + Debug,
587 isize: TryFrom<T>,
588 <T as TryInto<usize>>::Error: Debug,
589 <T as TryFrom<usize>>::Error: Debug,
590 <isize as TryFrom<T>>::Error: Debug,
591{
592 type Output = BoolExprNode<T>;
593
594 fn less_than(self, rhs: Self) -> Self::Output {
595 assert_eq!(self.indexes.len(), rhs.indexes.len());
596 let lhs_sign = self.bit(self.indexes.len() - 1);
597 let rhs_sign = rhs.bit(self.indexes.len() - 1);
598 let (lhs_num, rhs_num) = {
599 let mut lhs_num = self.as_unsigned();
600 let mut rhs_num = rhs.as_unsigned();
601 *lhs_num.indexes.last_mut().unwrap() = 0;
602 *rhs_num.indexes.last_mut().unwrap() = 0;
603 (lhs_num, rhs_num)
604 };
605 (lhs_sign.clone() & (!rhs_sign.clone()))
606 | (lhs_sign.bequal(rhs_sign) & lhs_num.less_than(rhs_num))
607 }
608
609 fn less_equal(self, rhs: Self) -> Self::Output {
610 assert_eq!(self.indexes.len(), rhs.indexes.len());
611 let lhs_sign = self.bit(self.indexes.len() - 1);
612 let rhs_sign = rhs.bit(self.indexes.len() - 1);
613 let (lhs_num, rhs_num) = {
614 let mut lhs_num = self.as_unsigned();
615 let mut rhs_num = rhs.as_unsigned();
616 *lhs_num.indexes.last_mut().unwrap() = 0;
617 *rhs_num.indexes.last_mut().unwrap() = 0;
618 (lhs_num, rhs_num)
619 };
620 (lhs_sign.clone() & (!rhs_sign.clone()))
621 | (lhs_sign.bequal(rhs_sign) & lhs_num.less_equal(rhs_num))
622 }
623
624 fn greater_than(self, rhs: Self) -> Self::Output {
625 rhs.less_than(self)
626 }
627
628 fn greater_equal(self, rhs: Self) -> Self::Output {
629 rhs.less_equal(self)
630 }
631}
632
633pub type UDynExprNode<T> = DynIntExprNode<T, false>;
637pub type IDynExprNode<T> = DynIntExprNode<T, true>;
639
640#[cfg(test)]
641mod tests {
642 use super::*;
643 use crate::intexpr::IntExprNode;
644 use generic_array::typenum::*;
645 use std::iter;
646
647 #[test]
648 fn test_expr_node() {
649 let ec = ExprCreator::new();
650 let x1 = DynIntExprNode::<isize, false>::variable(ec.clone(), 7);
651 assert_eq!([2, 3, 4, 5, 6, 7, 8], *x1.indexes);
652 assert_eq!([2, 3, 4, 5, 6, 7, 8], *(x1.clone().as_signed()).indexes);
653 assert_eq!([2, 3, 4, 5, 6, 7, 8], *(x1.as_unsigned()).indexes);
654 let x2 = DynIntExprNode::<isize, true>::variable(ec.clone(), 7);
655 assert_eq!([9, 10, 11, 12, 13, 14, 15], *x2.indexes);
656 assert_eq!(
657 [9, 10, 11, 12, 13, 14, 15],
658 *(x2.clone().as_unsigned()).indexes
659 );
660 assert_eq!([9, 10, 11, 12, 13, 14, 15], *(x2.as_signed()).indexes);
661
662 let b1 = BoolExprNode::variable(ec.clone());
663 let x3 = DynIntExprNode::<isize, false>::filled(ec.clone(), 4, b1.varlit().unwrap());
664 assert_eq!([16, 16, 16, 16], *x3.indexes);
665 let b1 = BoolExprNode::variable(ec.clone());
666 let b2 = BoolExprNode::variable(ec.clone());
667 let bxp = b1.clone() ^ b2.clone();
668 let x4 = DynIntExprNode::<isize, false>::filled_expr(4, bxp.clone());
669 assert_eq!(
670 iter::repeat(bxp.index)
671 .take(4)
672 .collect::<Vec<_>>()
673 .as_slice(),
674 x4.indexes.as_slice()
675 );
676
677 let b3 = BoolExprNode::variable(ec.clone());
679 let b4 = BoolExprNode::variable(ec.clone());
680 let bxps = [
681 b1.clone() & b2.clone(),
682 b1.clone() | b2.clone(),
683 b1.clone() ^ b2.clone(),
684 b1 | b2.clone() | b3.clone(),
685 b3.clone() & b4.clone(),
686 b3.clone() | b4.clone(),
687 b3.clone() ^ b4.clone(),
688 b2 | b3 | b4,
689 ];
690
691 let x5 = DynIntExprNode::<isize, false>::from_boolexprs(bxps.clone());
692 assert_eq!(
693 bxps.iter().map(|x| x.index).collect::<Vec<_>>().as_slice(),
694 x5.indexes.as_slice()
695 );
696 }
697
698 #[test]
699 fn test_expr_node_manip() {
700 let ec = ExprCreator::new();
701 let x1 = DynIntExprNode::<isize, false>::variable(ec.clone(), 16);
702 let x2 = x1.subvalue(7, 6);
703 assert_eq!([9, 10, 11, 12, 13, 14], *x2.indexes);
704 let x3 = x1.select_bits([3, 8, 9, 0, 3, 4, 12, 14, 15]);
705 assert_eq!([5, 10, 11, 2, 5, 6, 14, 16, 17], *x3.indexes);
706
707 let y1 = DynIntExprNode::<isize, false>::variable(ec.clone(), 8);
708 let z1 = x1.clone().concat(y1.clone());
709 assert_eq!(
710 (2..(2 + 24)).into_iter().collect::<Vec<usize>>().as_slice(),
711 z1.indexes.as_slice()
712 );
713 let z1 = y1.concat(x1);
714 assert_eq!(
715 ((2 + 16)..(2 + 24))
716 .into_iter()
717 .chain((2..18).into_iter())
718 .collect::<Vec<usize>>()
719 .as_slice(),
720 z1.indexes.as_slice()
721 );
722 let (xt1, xt2) = z1.split(5);
723 assert_eq!([18, 19, 20, 21, 22], *xt1.indexes);
724 assert_eq!(
725 ((2 + 16 + 5)..(2 + 24))
726 .into_iter()
727 .chain((2..18).into_iter())
728 .collect::<Vec<usize>>()
729 .as_slice(),
730 xt2.indexes.as_slice()
731 );
732 }
733
734 #[test]
735 fn test_expr_node_from_int_expr_node() {
736 let ec = ExprCreator::new();
737 let ix1 = IntExprNode::<isize, U10, false>::variable(ec.clone());
738 let dix1 = DynIntExprNode::<isize, false>::from(ix1.clone());
739 assert_eq!(ix1.indexes.as_slice(), dix1.indexes.as_slice());
740 }
741
742 #[test]
743 fn test_expr_node_try_from_n_uncond() {
744 let ec = ExprCreator::new();
745 let x1 = DynIntExprNode::<isize, false>::variable(ec.clone(), 8);
747 let x2 = DynIntExprNode::<isize, false>::try_from_n(x1.clone(), 14).unwrap();
748 assert_eq!([2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0], *x2.indexes);
749 let ix2 = DynIntExprNode::<isize, true>::try_from_n(x1.clone(), 14).unwrap();
751 assert_eq!([2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0], *ix2.indexes);
752 let ix1 = DynIntExprNode::<isize, true>::variable(ec.clone(), 8);
753 let ix2 = DynIntExprNode::<isize, true>::try_from_n(ix1.clone(), 12).unwrap();
755 assert_eq!(
756 [10, 11, 12, 13, 14, 15, 16, 17, 17, 17, 17, 17],
757 *ix2.indexes
758 );
759 }
760
761 #[test]
762 fn test_expr_node_try_from_n() {
763 let ec = ExprCreator::new();
764 let ix1 = DynIntExprNode::<isize, true>::try_from_n(
765 DynIntExprNode::<isize, false>::variable(ec.clone(), 7),
766 8,
767 )
768 .unwrap();
769 let x1 = DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 8).unwrap();
771 assert_eq!([2, 3, 4, 5, 6, 7, 8, 0], *x1.indexes);
772 let x2 = DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 9).unwrap();
774 assert_eq!([2, 3, 4, 5, 6, 7, 8, 0, 0], *x2.indexes);
775 let x2 = DynIntExprNode::<isize, false>::try_from_n(ix1, 10).unwrap();
776 assert_eq!([2, 3, 4, 5, 6, 7, 8, 0, 0, 0], *x2.indexes);
777
778 let ix1 = DynIntExprNode::<isize, true>::try_from_n(
779 DynIntExprNode::<isize, true>::variable(ec.clone(), 7),
780 8,
781 )
782 .unwrap();
783 assert_eq!(
785 Err("Value can be negative".to_string()),
786 DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 8).map_err(|x| x.to_string())
787 );
788 assert_eq!(
790 Err("Value can be negative".to_string()),
791 DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 9).map_err(|x| x.to_string())
792 );
793 assert_eq!(
794 Err("Value can be negative".to_string()),
795 DynIntExprNode::<isize, false>::try_from_n(ix1, 10).map_err(|x| x.to_string())
796 );
797
798 let x1 = DynIntExprNode::<isize, false>::try_from_n(
799 DynIntExprNode::<isize, false>::variable(ec.clone(), 7),
800 8,
801 )
802 .unwrap();
803 let ix2 = DynIntExprNode::<isize, true>::try_from_n(x1.clone(), 8).unwrap();
805 assert_eq!([16, 17, 18, 19, 20, 21, 22, 0], *ix2.indexes);
806 let ix2 = DynIntExprNode::<isize, true>::try_from_n(x1.clone(), 9).unwrap();
808 assert_eq!([16, 17, 18, 19, 20, 21, 22, 0, 0], *ix2.indexes);
809
810 let x1 = DynIntExprNode::<isize, false>::variable(ec.clone(), 8);
811 let ix2 = DynIntExprNode::<isize, true>::try_from_n(x1.clone(), 9).unwrap();
813 assert_eq!([23, 24, 25, 26, 27, 28, 29, 30, 0], *ix2.indexes);
814 assert_eq!(
816 Err("Bit overflow".to_string()),
817 DynIntExprNode::<isize, true>::try_from_n(x1.clone(), 8).map_err(|x| x.to_string())
818 );
819
820 let ux1 = DynIntExprNode::<isize, false>::try_from_n(
823 DynIntExprNode::<isize, false>::variable(ec.clone(), 6),
824 8,
825 )
826 .unwrap();
827 let x2 = DynIntExprNode::<isize, false>::try_from_n(ux1.clone(), 6).unwrap();
829 assert_eq!([31, 32, 33, 34, 35, 36], *x2.indexes);
830 assert_eq!(
832 Err("Bit overflow".to_string()),
833 DynIntExprNode::<isize, false>::try_from_n(ux1.clone(), 5).map_err(|x| x.to_string())
834 );
835 assert_eq!(
836 Err("Bit overflow".to_string()),
837 DynIntExprNode::<isize, false>::try_from_n(ux1.clone(), 4).map_err(|x| x.to_string())
838 );
839 let ix2 = DynIntExprNode::<isize, true>::try_from_n(ux1.clone(), 7).unwrap();
840 assert_eq!([31, 32, 33, 34, 35, 36, 0], *ix2.indexes);
842 assert_eq!(
844 Err("Bit overflow".to_string()),
845 DynIntExprNode::<isize, true>::try_from_n(ux1.clone(), 6).map_err(|x| x.to_string())
846 );
847 assert_eq!(
848 Err("Bit overflow".to_string()),
849 DynIntExprNode::<isize, true>::try_from_n(ux1.clone(), 5).map_err(|x| x.to_string())
850 );
851
852 let ix1 = DynIntExprNode::<isize, true>::try_from_n(
853 DynIntExprNode::<isize, false>::variable(ec.clone(), 6),
854 8,
855 )
856 .unwrap();
857 let x2 = DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 6).unwrap();
859 assert_eq!([37, 38, 39, 40, 41, 42], *x2.indexes);
860 assert_eq!(
862 Err("Bit overflow".to_string()),
863 DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 5).map_err(|x| x.to_string())
864 );
865 let ix2 = DynIntExprNode::<isize, true>::try_from_n(ix1.clone(), 7).unwrap();
867 assert_eq!([37, 38, 39, 40, 41, 42, 0], *ix2.indexes);
868 assert_eq!(
870 Err("Bit overflow".to_string()),
871 DynIntExprNode::<isize, true>::try_from_n(ix1.clone(), 6).map_err(|x| x.to_string())
872 );
873 assert_eq!(
874 Err("Bit overflow".to_string()),
875 DynIntExprNode::<isize, true>::try_from_n(ix1.clone(), 5).map_err(|x| x.to_string())
876 );
877
878 let ix1 = DynIntExprNode::<isize, true>::try_from_n(
880 DynIntExprNode::<isize, true>::variable(ec.clone(), 6),
881 8,
882 )
883 .unwrap();
884 assert_eq!(
886 Err("Bit overflow".to_string()),
887 DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 6).map_err(|x| x.to_string())
888 );
889 assert_eq!(
890 Err("Bit overflow".to_string()),
891 DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 5).map_err(|x| x.to_string())
892 );
893 assert_eq!(
895 Err("Bit overflow".to_string()),
896 DynIntExprNode::<isize, false>::try_from_n(ix1.clone(), 7).map_err(|x| x.to_string())
897 );
898 let ix2 = DynIntExprNode::<isize, true>::try_from_n(ix1.clone(), 6).unwrap();
899 assert_eq!([43, 44, 45, 46, 47, 48], *ix2.indexes);
901 assert_eq!(
903 Err("Bit overflow".to_string()),
904 DynIntExprNode::<isize, true>::try_from_n(ix1.clone(), 5).map_err(|x| x.to_string())
905 );
906 assert_eq!(
907 Err("Bit overflow".to_string()),
908 DynIntExprNode::<isize, true>::try_from_n(ix1.clone(), 5).map_err(|x| x.to_string())
909 );
910 }
911
912 #[test]
913 fn test_expr_node_try_int_constant_n() {
914 let ec = ExprCreator::new();
915 let x1 =
916 DynIntExprNode::<isize, false>::try_constant_n(ec.clone(), 9, 0b11011001u16).unwrap();
917 assert_eq!([1, 0, 0, 1, 1, 0, 1, 1, 0], *x1.indexes);
918 let x1 =
919 DynIntExprNode::<isize, true>::try_constant_n(ec.clone(), 8, 0b00111001i16).unwrap();
920 assert_eq!([1, 0, 0, 1, 1, 1, 0, 0], *x1.indexes);
921 let x1 = DynIntExprNode::<isize, true>::try_constant_n(ec.clone(), 10, -15i8).unwrap();
922 assert_eq!([1, 0, 0, 0, 1, 1, 1, 1, 1, 1], *x1.indexes);
923 let x1 =
924 DynIntExprNode::<isize, false>::try_constant_n(ec.clone(), 64, 1848549293434211u64)
925 .unwrap();
926 assert_eq!(
927 (0..64)
928 .into_iter()
929 .map(|x| ((1848549293434211u64 >> x) & 1) as usize)
930 .collect::<Vec<_>>()
931 .as_slice(),
932 x1.indexes.as_slice()
933 );
934 let x1 = DynIntExprNode::<isize, true>::try_constant_n(ec.clone(), 1, 0i64).unwrap();
935 assert_eq!([0], *x1.indexes);
936 for i in 4..16 {
937 assert_eq!(
938 Err("Bit overflow".to_string()),
939 DynIntExprNode::<isize, false>::try_constant_n(ec.clone(), 4, 14u16 | (1u16 << i))
940 .map_err(|x| x.to_string())
941 );
942 }
943 for i in 4..16 {
944 assert_eq!(
945 Err("Bit overflow".to_string()),
946 DynIntExprNode::<isize, true>::try_constant_n(ec.clone(), 4, 6i16 | (1i16 << i))
947 .map_err(|x| x.to_string())
948 );
949 }
950 for i in 4..16 {
951 assert_eq!(
952 Err("Bit overflow".to_string()),
953 DynIntExprNode::<isize, true>::try_constant_n(ec.clone(), 4, (-6i16) ^ (1i16 << i))
954 .map_err(|x| x.to_string())
955 );
956 }
957 }
958
959 #[test]
960 fn test_expr_node_bitval() {
961 let ec = ExprCreator::new();
962 let x1 = DynIntExprNode::<isize, false>::variable(ec.clone(), 7);
963 assert_eq!(x1.bit(2), BoolExprNode::single(ec.clone(), 3));
964 assert_eq!(x1.bit(6), BoolExprNode::single(ec.clone(), 7));
965 let x1 = DynIntExprNode::<isize, true>::variable(ec.clone(), 7);
966 assert_eq!(x1.bit(3), BoolExprNode::single(ec.clone(), 11));
967 }
968
969 #[test]
970 fn test_expr_node_int_equal() {
971 let ec = ExprCreator::new();
972 let x1 = DynIntExprNode::<isize, false>::variable(ec.clone(), 5);
973 let x2 = DynIntExprNode::<isize, false>::variable(ec.clone(), 5);
974 let x3 = DynIntExprNode::<isize, false>::variable(ec.clone(), 5);
975 let x4 = DynIntExprNode::<isize, false>::variable(ec.clone(), 5);
976 let reseq = x1.equal(x2);
977 let resne = x3.nequal(x4);
978
979 let exp_ec = ExprCreator::new();
980 let x1 = IntExprNode::<isize, U5, false>::variable(exp_ec.clone());
981 let x2 = IntExprNode::<isize, U5, false>::variable(exp_ec.clone());
982 let x3 = IntExprNode::<isize, U5, false>::variable(exp_ec.clone());
983 let x4 = IntExprNode::<isize, U5, false>::variable(exp_ec.clone());
984 let expeq = x1.equal(x2);
985 let expne = x3.nequal(x4);
986
987 assert_eq!(expeq, reseq);
988 assert_eq!(expne, resne);
989 assert_eq!(*exp_ec.borrow(), *ec.borrow());
990 }
991
992 macro_rules! test_int_ord_macro {
993 ($sign:expr) => {
994 let ec = ExprCreator::new();
995 let xv = (0..8)
996 .into_iter()
997 .map(|_| DynIntExprNode::<isize, $sign>::variable(ec.clone(), 5))
998 .collect::<Vec<_>>();
999 let reslt = xv[0].clone().less_than(xv[1].clone());
1000 let resle = xv[2].clone().less_equal(xv[3].clone());
1001 let resgt = xv[4].clone().greater_than(xv[5].clone());
1002 let resge = xv[6].clone().greater_equal(xv[7].clone());
1003
1004 let exp_ec = ExprCreator::new();
1005 let xv = (0..8)
1006 .into_iter()
1007 .map(|_| IntExprNode::<isize, U5, $sign>::variable(exp_ec.clone()))
1008 .collect::<Vec<_>>();
1009 let explt = xv[0].clone().less_than(xv[1].clone());
1010 let exple = xv[2].clone().less_equal(xv[3].clone());
1011 let expgt = xv[4].clone().greater_than(xv[5].clone());
1012 let expge = xv[6].clone().greater_equal(xv[7].clone());
1013
1014 assert_eq!(explt, reslt);
1015 assert_eq!(exple, resle);
1016 assert_eq!(expgt, resgt);
1017 assert_eq!(expge, resge);
1018 assert_eq!(*exp_ec.borrow(), *ec.borrow());
1019 };
1020 }
1021
1022 #[test]
1023 fn test_expr_node_int_ord() {
1024 test_int_ord_macro!(false);
1025 test_int_ord_macro!(true);
1026 }
1027}