@@ -1254,6 +1254,13 @@ impl<FV> Refinement<FV> {
12541254 refinement : self ,
12551255 }
12561256 }
1257+
1258+ pub fn subst_ty_params_in_sorts < T > ( & mut self , subst : & TypeParamSubst < T > ) {
1259+ for sort in & mut self . existentials {
1260+ subst_ty_params_in_sort ( sort, subst) ;
1261+ }
1262+ subst_ty_params_in_body ( & mut self . body , subst) ;
1263+ }
12571264}
12581265
12591266/// A helper type to map logical variables in a refinement at once.
@@ -1445,6 +1452,7 @@ impl<FV> RefinedType<FV> {
14451452 where
14461453 FV : chc:: Var ,
14471454 {
1455+ self . refinement . subst_ty_params_in_sorts ( subst) ;
14481456 match & mut self . ty {
14491457 Type :: Int | Type :: Bool | Type :: String | Type :: Never => { }
14501458 Type :: Param ( ty) => {
@@ -1513,6 +1521,108 @@ impl RefinedType<Closed> {
15131521 }
15141522}
15151523
1524+ /// Substitutes type parameters in a sort.
1525+ fn subst_ty_params_in_sort < T > ( sort : & mut chc:: Sort , subst : & TypeParamSubst < T > ) {
1526+ match sort {
1527+ chc:: Sort :: Null | chc:: Sort :: Int | chc:: Sort :: Bool | chc:: Sort :: String => { }
1528+ chc:: Sort :: Param ( idx) => {
1529+ let type_param_idx = TypeParamIdx :: from_usize ( * idx) ;
1530+ if let Some ( rty) = subst. get ( type_param_idx) {
1531+ * sort = rty. ty . to_sort ( ) ;
1532+ }
1533+ }
1534+ chc:: Sort :: Box ( s) | chc:: Sort :: Mut ( s) => {
1535+ subst_ty_params_in_sort ( s, subst) ;
1536+ }
1537+ chc:: Sort :: Tuple ( sorts) => {
1538+ for s in sorts {
1539+ subst_ty_params_in_sort ( s, subst) ;
1540+ }
1541+ }
1542+ chc:: Sort :: Datatype ( dt_sort) => {
1543+ for s in dt_sort. args_mut ( ) {
1544+ subst_ty_params_in_sort ( s, subst) ;
1545+ }
1546+ }
1547+ }
1548+ }
1549+
1550+ /// Substitutes type parameters in all sorts appearing in a body.
1551+ fn subst_ty_params_in_body < T , V > ( body : & mut chc:: Body < V > , subst : & TypeParamSubst < T > ) {
1552+ for atom in & mut body. atoms {
1553+ subst_ty_params_in_atom ( atom, subst) ;
1554+ }
1555+ subst_ty_params_in_formula ( & mut body. formula , subst) ;
1556+ }
1557+
1558+ /// Substitutes type parameters in all sorts appearing in an atom.
1559+ fn subst_ty_params_in_atom < T , V > ( atom : & mut chc:: Atom < V > , subst : & TypeParamSubst < T > ) {
1560+ if let Some ( guard) = & mut atom. guard {
1561+ subst_ty_params_in_formula ( guard, subst) ;
1562+ }
1563+ for term in & mut atom. args {
1564+ subst_ty_params_in_term ( term, subst) ;
1565+ }
1566+ }
1567+
1568+ /// Substitutes type parameters in all sorts appearing in a formula.
1569+ fn subst_ty_params_in_formula < T , V > ( formula : & mut chc:: Formula < V > , subst : & TypeParamSubst < T > ) {
1570+ match formula {
1571+ chc:: Formula :: Atom ( atom) => subst_ty_params_in_atom ( atom, subst) ,
1572+ chc:: Formula :: Not ( f) => subst_ty_params_in_formula ( f, subst) ,
1573+ chc:: Formula :: And ( fs) | chc:: Formula :: Or ( fs) => {
1574+ for f in fs {
1575+ subst_ty_params_in_formula ( f, subst) ;
1576+ }
1577+ }
1578+ chc:: Formula :: Exists ( vars, f) => {
1579+ for ( _, sort) in vars {
1580+ subst_ty_params_in_sort ( sort, subst) ;
1581+ }
1582+ subst_ty_params_in_formula ( f, subst) ;
1583+ }
1584+ }
1585+ }
1586+
1587+ /// Substitutes type parameters in all sorts appearing in a term.
1588+ fn subst_ty_params_in_term < T , V > ( term : & mut chc:: Term < V > , subst : & TypeParamSubst < T > ) {
1589+ match term {
1590+ chc:: Term :: Null
1591+ | chc:: Term :: Var ( _)
1592+ | chc:: Term :: Bool ( _)
1593+ | chc:: Term :: Int ( _)
1594+ | chc:: Term :: String ( _) => { }
1595+ chc:: Term :: Box ( t)
1596+ | chc:: Term :: BoxCurrent ( t)
1597+ | chc:: Term :: MutCurrent ( t)
1598+ | chc:: Term :: MutFinal ( t)
1599+ | chc:: Term :: TupleProj ( t, _)
1600+ | chc:: Term :: DatatypeDiscr ( _, t) => {
1601+ subst_ty_params_in_term ( t, subst) ;
1602+ }
1603+ chc:: Term :: Mut ( t1, t2) => {
1604+ subst_ty_params_in_term ( t1, subst) ;
1605+ subst_ty_params_in_term ( t2, subst) ;
1606+ }
1607+ chc:: Term :: App ( _, args) | chc:: Term :: Tuple ( args) => {
1608+ for arg in args {
1609+ subst_ty_params_in_term ( arg, subst) ;
1610+ }
1611+ }
1612+ chc:: Term :: DatatypeCtor ( s, _, args) => {
1613+ for arg in s. args_mut ( ) {
1614+ subst_ty_params_in_sort ( arg, subst) ;
1615+ }
1616+ for arg in args {
1617+ subst_ty_params_in_term ( arg, subst) ;
1618+ }
1619+ }
1620+ chc:: Term :: FormulaExistentialVar ( sort, _) => {
1621+ subst_ty_params_in_sort ( sort, subst) ;
1622+ }
1623+ }
1624+ }
1625+
15161626pub fn unify_tys_params < I1 , I2 , T > ( tys1 : I1 , tys2 : I2 ) -> TypeParamSubst < T >
15171627where
15181628 T : chc:: Var ,
0 commit comments