|
8 | 8 |
|
9 | 9 | from pyk.cterm import CSubst, CTerm |
10 | 10 | from pyk.kast.inner import KApply, KSequence, KSort, KToken, KVariable, Subst |
11 | | -from pyk.kast.manip import minimize_term |
| 11 | +from pyk.kast.manip import get_cell, minimize_term |
12 | 12 | from pyk.kcfg.semantics import KCFGSemantics |
13 | 13 | from pyk.kcfg.show import KCFGShow |
14 | | -from pyk.prelude.kbool import BOOL, notBool |
| 14 | +from pyk.prelude.kbool import BOOL, notBool, orBool |
15 | 15 | from pyk.prelude.kint import intToken |
16 | 16 | from pyk.prelude.ml import mlAnd, mlBottom, mlEqualsFalse, mlEqualsTrue, mlTop |
17 | 17 | from pyk.proof import APRBMCProof, APRBMCProver, APRProof, APRProver, ProofStatus |
@@ -1147,3 +1147,137 @@ def test_fail_fast( |
1147 | 1147 | assert len(proof.pending) == 1 |
1148 | 1148 | assert len(proof.terminal) == 1 |
1149 | 1149 | assert len(proof.failing) == 1 |
| 1150 | + |
| 1151 | + def test_anti_unify_forget_values( |
| 1152 | + self, |
| 1153 | + kcfg_explore: KCFGExplore, |
| 1154 | + kprint: KPrint, |
| 1155 | + ) -> None: |
| 1156 | + cterm1 = self.config( |
| 1157 | + kprint=kprint, |
| 1158 | + k='int $n ; { }', |
| 1159 | + state='N |-> X:Int', |
| 1160 | + constraint=mlAnd( |
| 1161 | + [ |
| 1162 | + mlEqualsTrue(KApply('_>Int_', [KVariable('K', 'Int'), KToken('1', 'Int')])), |
| 1163 | + mlEqualsTrue(KApply('_>Int_', [KVariable('N', 'Int'), KToken('1', 'Int')])), |
| 1164 | + mlEqualsTrue(KApply('_>Int_', [KVariable('X', 'Int'), KToken('1', 'Int')])), |
| 1165 | + mlEqualsTrue(KApply('_>Int_', [KVariable('Y', 'Int'), KToken('1', 'Int')])), |
| 1166 | + ] |
| 1167 | + ), |
| 1168 | + ) |
| 1169 | + cterm2 = self.config( |
| 1170 | + kprint=kprint, |
| 1171 | + k='int $n ; { }', |
| 1172 | + state='N |-> Y:Int', |
| 1173 | + constraint=mlAnd( |
| 1174 | + [ |
| 1175 | + mlEqualsTrue(KApply('_>Int_', [KVariable('K', 'Int'), KToken('1', 'Int')])), |
| 1176 | + mlEqualsTrue(KApply('_>Int_', [KVariable('N', 'Int'), KToken('1', 'Int')])), |
| 1177 | + mlEqualsTrue(KApply('_>Int_', [KVariable('X', 'Int'), KToken('1', 'Int')])), |
| 1178 | + mlEqualsTrue(KApply('_>Int_', [KVariable('Y', 'Int'), KToken('1', 'Int')])), |
| 1179 | + ] |
| 1180 | + ), |
| 1181 | + ) |
| 1182 | + |
| 1183 | + anti_unifier, subst1, subst2 = cterm1.anti_unify(cterm2, keep_values=False, kdef=kprint.definition) |
| 1184 | + |
| 1185 | + k_cell = get_cell(anti_unifier.kast, 'STATE_CELL') |
| 1186 | + assert type(k_cell) is KApply |
| 1187 | + assert k_cell.label.name == '_|->_' |
| 1188 | + assert type(k_cell.args[1]) is KVariable |
| 1189 | + abstracted_var: KVariable = k_cell.args[1] |
| 1190 | + |
| 1191 | + expected_anti_unifier = self.config( |
| 1192 | + kprint=kprint, |
| 1193 | + k='int $n ; { }', |
| 1194 | + state=f'N |-> {abstracted_var.name}:Int', |
| 1195 | + constraint=mlEqualsTrue(KApply('_>Int_', [KVariable('N', 'Int'), KToken('1', 'Int')])), |
| 1196 | + ) |
| 1197 | + |
| 1198 | + assert anti_unifier.kast == expected_anti_unifier.kast |
| 1199 | + |
| 1200 | + def test_anti_unify_keep_values( |
| 1201 | + self, |
| 1202 | + kcfg_explore: KCFGExplore, |
| 1203 | + kprint: KPrint, |
| 1204 | + ) -> None: |
| 1205 | + cterm1 = self.config( |
| 1206 | + kprint=kprint, |
| 1207 | + k='int $n ; { }', |
| 1208 | + state='N |-> X:Int', |
| 1209 | + constraint=mlAnd( |
| 1210 | + [ |
| 1211 | + mlEqualsTrue(KApply('_>Int_', [KVariable('K', 'Int'), KToken('1', 'Int')])), |
| 1212 | + mlEqualsTrue(KApply('_>Int_', [KVariable('N', 'Int'), KToken('1', 'Int')])), |
| 1213 | + mlEqualsTrue(KApply('_>Int_', [KVariable('X', 'Int'), KToken('1', 'Int')])), |
| 1214 | + mlEqualsTrue(KApply('_>Int_', [KVariable('Y', 'Int'), KToken('1', 'Int')])), |
| 1215 | + ] |
| 1216 | + ), |
| 1217 | + ) |
| 1218 | + cterm2 = self.config( |
| 1219 | + kprint=kprint, |
| 1220 | + k='int $n ; { }', |
| 1221 | + state='N |-> Y:Int', |
| 1222 | + constraint=mlAnd( |
| 1223 | + [ |
| 1224 | + mlEqualsTrue(KApply('_>Int_', [KVariable('K', 'Int'), KToken('1', 'Int')])), |
| 1225 | + mlEqualsTrue(KApply('_>Int_', [KVariable('N', 'Int'), KToken('1', 'Int')])), |
| 1226 | + mlEqualsTrue(KApply('_>Int_', [KVariable('X', 'Int'), KToken('1', 'Int')])), |
| 1227 | + mlEqualsTrue(KApply('_>Int_', [KVariable('Y', 'Int'), KToken('1', 'Int')])), |
| 1228 | + ] |
| 1229 | + ), |
| 1230 | + ) |
| 1231 | + |
| 1232 | + anti_unifier, subst1, subst2 = cterm1.anti_unify(cterm2, keep_values=True, kdef=kprint.definition) |
| 1233 | + |
| 1234 | + k_cell = get_cell(anti_unifier.kast, 'STATE_CELL') |
| 1235 | + assert type(k_cell) is KApply |
| 1236 | + assert k_cell.label.name == '_|->_' |
| 1237 | + assert type(k_cell.args[1]) is KVariable |
| 1238 | + abstracted_var: KVariable = k_cell.args[1] |
| 1239 | + |
| 1240 | + expected_anti_unifier = self.config( |
| 1241 | + kprint=kprint, |
| 1242 | + k='int $n ; { }', |
| 1243 | + state=f'N |-> {abstracted_var.name}:Int', |
| 1244 | + constraint=mlAnd( |
| 1245 | + [ |
| 1246 | + mlEqualsTrue(KApply('_>Int_', [KVariable('N', 'Int'), KToken('1', 'Int')])), |
| 1247 | + mlEqualsTrue(KApply('_>Int_', [KVariable('X', 'Int'), KToken('1', 'Int')])), |
| 1248 | + mlEqualsTrue(KApply('_>Int_', [KVariable('Y', 'Int'), KToken('1', 'Int')])), |
| 1249 | + mlEqualsTrue( |
| 1250 | + orBool( |
| 1251 | + [ |
| 1252 | + KApply('_==K_', [KVariable(name=abstracted_var.name), KVariable('X', 'Int')]), |
| 1253 | + KApply('_==K_', [KVariable(name=abstracted_var.name), KVariable('Y', 'Int')]), |
| 1254 | + ] |
| 1255 | + ) |
| 1256 | + ), |
| 1257 | + ] |
| 1258 | + ), |
| 1259 | + ) |
| 1260 | + |
| 1261 | + assert anti_unifier.kast == expected_anti_unifier.kast |
| 1262 | + |
| 1263 | + def test_anti_unify_subst_true( |
| 1264 | + self, |
| 1265 | + kcfg_explore: KCFGExplore, |
| 1266 | + kprint: KPrint, |
| 1267 | + ) -> None: |
| 1268 | + cterm1 = self.config( |
| 1269 | + kprint=kprint, |
| 1270 | + k='int $n ; { }', |
| 1271 | + state='N |-> 0', |
| 1272 | + constraint=mlEqualsTrue(KApply('_==K_', [KVariable('N', 'Int'), KToken('1', 'Int')])), |
| 1273 | + ) |
| 1274 | + cterm2 = self.config( |
| 1275 | + kprint=kprint, |
| 1276 | + k='int $n ; { }', |
| 1277 | + state='N |-> 0', |
| 1278 | + constraint=mlEqualsTrue(KApply('_==K_', [KVariable('N', 'Int'), KToken('1', 'Int')])), |
| 1279 | + ) |
| 1280 | + |
| 1281 | + anti_unifier, _, _ = cterm1.anti_unify(cterm2, keep_values=True, kdef=kprint.definition) |
| 1282 | + |
| 1283 | + assert anti_unifier.kast == cterm1.kast |
0 commit comments