@@ -437,14 +437,12 @@ impl Function {
437437}
438438
439439#[ derive( Debug , Clone ) ]
440- pub struct ArrayConcatTerm < V = TermVarIdx > {
441- pub array1 : Term < V > ,
442- pub len1 : Term < V > ,
443- pub array2 : Term < V > ,
444- pub len2 : Term < V > ,
440+ pub struct SeqConcatTerm < V = TermVarIdx > {
441+ pub seq1 : Term < V > ,
442+ pub seq2 : Term < V > ,
445443}
446444
447- impl < ' a , D , V > Pretty < ' a , D , termcolor:: ColorSpec > for & ArrayConcatTerm < V >
445+ impl < ' a , D , V > Pretty < ' a , D , termcolor:: ColorSpec > for & SeqConcatTerm < V >
448446where
449447 V : Var ,
450448 D : pretty:: DocAllocator < ' a , termcolor:: ColorSpec > ,
@@ -454,44 +452,30 @@ where
454452 allocator
455453 . text ( "concat" )
456454 . append ( allocator. line ( ) )
457- . append ( self . array1 . pretty_atom ( allocator) )
455+ . append ( self . seq1 . pretty_atom ( allocator) )
458456 . append ( allocator. text ( "," ) )
459457 . append ( allocator. line ( ) )
460- . append ( self . len1 . pretty_atom ( allocator) )
461- . append ( allocator. text ( "," ) )
462- . append ( allocator. line ( ) )
463- . append ( self . array2 . pretty_atom ( allocator) )
464- . append ( allocator. text ( "," ) )
465- . append ( allocator. line ( ) )
466- . append ( self . len2 . pretty_atom ( allocator) )
458+ . append ( self . seq2 . pretty_atom ( allocator) )
467459 . parens ( )
468460 }
469461}
470462
471- impl < V > ArrayConcatTerm < V > {
463+ impl < V > SeqConcatTerm < V > {
472464 pub fn iter_args ( & self ) -> impl Iterator < Item = & Term < V > > {
473- std:: iter:: once ( & self . array1 )
474- . chain ( std:: iter:: once ( & self . len1 ) )
475- . chain ( std:: iter:: once ( & self . array2 ) )
476- . chain ( std:: iter:: once ( & self . len2 ) )
465+ std:: iter:: once ( & self . seq1 ) . chain ( std:: iter:: once ( & self . seq2 ) )
477466 }
478467
479468 pub fn iter_args_mut ( & mut self ) -> impl Iterator < Item = & mut Term < V > > {
480- std:: iter:: once ( & mut self . array1 )
481- . chain ( std:: iter:: once ( & mut self . len1 ) )
482- . chain ( std:: iter:: once ( & mut self . array2 ) )
483- . chain ( std:: iter:: once ( & mut self . len2 ) )
469+ std:: iter:: once ( & mut self . seq1 ) . chain ( std:: iter:: once ( & mut self . seq2 ) )
484470 }
485471
486- pub fn subst_var < F , W > ( self , mut f : F ) -> ArrayConcatTerm < W >
472+ pub fn subst_var < F , W > ( self , mut f : F ) -> SeqConcatTerm < W >
487473 where
488474 F : FnMut ( V ) -> Term < W > ,
489475 {
490- ArrayConcatTerm {
491- array1 : self . array1 . subst_var ( & mut f) ,
492- len1 : self . len1 . subst_var ( & mut f) ,
493- array2 : self . array2 . subst_var ( & mut f) ,
494- len2 : self . len2 . subst_var ( f) ,
476+ SeqConcatTerm {
477+ seq1 : self . seq1 . subst_var ( & mut f) ,
478+ seq2 : self . seq2 . subst_var ( f) ,
495479 }
496480 }
497481}
@@ -511,7 +495,7 @@ pub enum Term<V = TermVarIdx> {
511495 MutFinal ( Box < Term < V > > ) ,
512496 App ( Function , Vec < Term < V > > ) ,
513497 ArrayEmpty ( Sort , Sort ) ,
514- ArrayConcat ( Sort , Box < ArrayConcatTerm < V > > ) ,
498+ SeqConcat ( Sort , Box < SeqConcatTerm < V > > ) ,
515499 Tuple ( Vec < Term < V > > ) ,
516500 TupleProj ( Box < Term < V > > , usize ) ,
517501 DatatypeCtor ( DatatypeSort , DatatypeSymbol , Vec < Term < V > > ) ,
@@ -564,7 +548,7 @@ where
564548 }
565549 }
566550 Term :: ArrayEmpty ( _, _) => allocator. text ( "[]" ) ,
567- Term :: ArrayConcat ( _, t) => t. pretty ( allocator) ,
551+ Term :: SeqConcat ( _, t) => t. pretty ( allocator) ,
568552 Term :: Tuple ( ts) => {
569553 let separator = allocator. text ( "," ) . append ( allocator. line ( ) ) ;
570554 if ts. len ( ) == 1 {
@@ -629,7 +613,7 @@ impl<V> Term<V> {
629613 Term :: App ( fun, args. into_iter ( ) . map ( |t| t. subst_var ( & mut f) ) . collect ( ) )
630614 }
631615 Term :: ArrayEmpty ( s1, s2) => Term :: ArrayEmpty ( s1, s2) ,
632- Term :: ArrayConcat ( s, t) => Term :: ArrayConcat ( s, Box :: new ( t. subst_var ( f) ) ) ,
616+ Term :: SeqConcat ( s, t) => Term :: SeqConcat ( s, Box :: new ( t. subst_var ( f) ) ) ,
633617 Term :: Tuple ( ts) => Term :: Tuple ( ts. into_iter ( ) . map ( |t| t. subst_var ( & mut f) ) . collect ( ) ) ,
634618 Term :: TupleProj ( t, i) => Term :: TupleProj ( Box :: new ( t. subst_var ( f) ) , i) ,
635619 Term :: DatatypeCtor ( sort, c_sym, args) => Term :: DatatypeCtor (
@@ -677,7 +661,7 @@ impl<V> Term<V> {
677661 fun. sort ( args. iter ( ) . map ( |t| t. sort ( & mut var_sort) ) )
678662 }
679663 Term :: ArrayEmpty ( index, elem) => Sort :: array ( index. clone ( ) , elem. clone ( ) ) ,
680- Term :: ArrayConcat ( elem, _) => Sort :: array ( Sort :: int ( ) , elem. clone ( ) ) ,
664+ Term :: SeqConcat ( elem, _) => Sort :: array ( Sort :: int ( ) , elem. clone ( ) ) ,
681665 Term :: Tuple ( ts) => {
682666 // TODO: remove this
683667 let mut var_sort: Box < dyn FnMut ( & V ) -> Sort > = Box :: new ( var_sort) ;
@@ -705,7 +689,7 @@ impl<V> Term<V> {
705689 Term :: MutCurrent ( t) => t. fv_impl ( ) ,
706690 Term :: MutFinal ( t) => t. fv_impl ( ) ,
707691 Term :: App ( _, args) => Box :: new ( args. iter ( ) . flat_map ( |t| t. fv_impl ( ) ) ) ,
708- Term :: ArrayConcat ( _, t) => Box :: new ( t. iter_args ( ) . flat_map ( |t| t. fv_impl ( ) ) ) ,
692+ Term :: SeqConcat ( _, t) => Box :: new ( t. iter_args ( ) . flat_map ( |t| t. fv_impl ( ) ) ) ,
709693 Term :: Tuple ( ts) => Box :: new ( ts. iter ( ) . flat_map ( |t| t. fv_impl ( ) ) ) ,
710694 Term :: TupleProj ( t, _) => t. fv_impl ( ) ,
711695 Term :: DatatypeCtor ( _, _, args) => Box :: new ( args. iter ( ) . flat_map ( |t| t. fv_impl ( ) ) ) ,
@@ -772,22 +756,8 @@ impl<V> Term<V> {
772756 Term :: ArrayEmpty ( index, elem)
773757 }
774758
775- pub fn array_concat (
776- elem_sort : Sort ,
777- array1 : Term < V > ,
778- len1 : Term < V > ,
779- array2 : Term < V > ,
780- len2 : Term < V > ,
781- ) -> Self {
782- Term :: ArrayConcat (
783- elem_sort,
784- Box :: new ( ArrayConcatTerm {
785- array1,
786- len1,
787- array2,
788- len2,
789- } ) ,
790- )
759+ pub fn seq_concat ( elem_sort : Sort , seq1 : Term < V > , seq2 : Term < V > ) -> Self {
760+ Term :: SeqConcat ( elem_sort, Box :: new ( SeqConcatTerm { seq1, seq2 } ) )
791761 }
792762
793763 pub fn boxed ( self ) -> Self {
@@ -893,18 +863,21 @@ impl<V> Term<V> {
893863 ] ,
894864 ) ;
895865 }
896- // Peephole 2: inline one step of the `concat_int_array ` recursive definitions to reduce
866+ // Peephole 2: inline one step of the `seq_concat ` recursive definitions to reduce
897867 // indexed access to terms over the underlying sequences. The SMT-defined functions are
898868 // still emitted (so the rewrites use exactly their unfolded form), but pcsat can prove
899869 // indexed properties against the inlined ITE for *any* recursion bound, where unfolding
900870 // through `define-fun-rec` would require an inductive invariant pcsat can't find.
901871 //
902- // `select(concat_int_array(sa, sn, ta, tn), i)
903- // ↦ ite(i < sn, select(sa, i), select(ta, i - sn))`
904- if let Term :: ArrayConcat ( _, t) = self {
905- let cond = index. clone ( ) . lt ( t. len1 . clone ( ) ) ;
906- let then_ = t. array1 . select ( index. clone ( ) ) ;
907- let else_ = t. array2 . select ( index. sub ( t. len1 ) ) ;
872+ // `select(seq_concat(s, t), i)
873+ // ↦ ite(i < len(s), select(array(s), i), select(array(t), i - len(s)))`
874+ // where `s`/`t` are `(array, length)` tuples.
875+ if let Term :: SeqConcat ( _, t) = self {
876+ let SeqConcatTerm { seq1, seq2 } = * t;
877+ let len1 = seq1. clone ( ) . tuple_proj ( 1 ) ;
878+ let cond = index. clone ( ) . lt ( len1. clone ( ) ) ;
879+ let then_ = seq1. tuple_proj ( 0 ) . select ( index. clone ( ) ) ;
880+ let else_ = seq2. tuple_proj ( 0 ) . select ( index. sub ( len1) ) ;
908881 return Term :: ite ( cond, then_, else_) ;
909882 }
910883 Term :: App ( Function :: SELECT , vec ! [ self , index] )
0 commit comments