490 | _ => lone_rep_fallback kk (Atom x) old_R r |
490 | _ => lone_rep_fallback kk (Atom x) old_R r |
491 and struct_from_rel_expr kk Rs old_R r = |
491 and struct_from_rel_expr kk Rs old_R r = |
492 case old_R of |
492 case old_R of |
493 Atom _ => lone_rep_fallback kk (Struct Rs) old_R r |
493 Atom _ => lone_rep_fallback kk (Struct Rs) old_R r |
494 | Struct Rs' => |
494 | Struct Rs' => |
495 let |
495 if Rs' = Rs then |
496 val Rs = filter (not_equal Unit) Rs |
496 r |
497 val Rs' = filter (not_equal Unit) Rs' |
497 else if map card_of_rep Rs' = map card_of_rep Rs then |
498 in |
498 let |
499 if Rs' = Rs then |
499 val old_arities = map arity_of_rep Rs' |
500 r |
500 val old_offsets = offset_list old_arities |
501 else if map card_of_rep Rs' = map card_of_rep Rs then |
501 val old_rs = map2 (#kk_project_seq kk r) old_offsets old_arities |
502 let |
502 in |
503 val old_arities = map arity_of_rep Rs' |
503 fold1 (#kk_product kk) |
504 val old_offsets = offset_list old_arities |
504 (map3 (rel_expr_from_rel_expr kk) Rs Rs' old_rs) |
505 val old_rs = map2 (#kk_project_seq kk r) old_offsets old_arities |
505 end |
506 in |
506 else |
507 fold1 (#kk_product kk) |
507 lone_rep_fallback kk (Struct Rs) old_R r |
508 (map3 (rel_expr_from_rel_expr kk) Rs Rs' old_rs) |
|
509 end |
|
510 else |
|
511 lone_rep_fallback kk (Struct Rs) old_R r |
|
512 end |
|
513 | _ => raise REP ("Nitpick_Kodkod.struct_from_rel_expr", [old_R]) |
508 | _ => raise REP ("Nitpick_Kodkod.struct_from_rel_expr", [old_R]) |
514 and vect_from_rel_expr kk k R old_R r = |
509 and vect_from_rel_expr kk k R old_R r = |
515 case old_R of |
510 case old_R of |
516 Atom _ => lone_rep_fallback kk (Vect (k, R)) old_R r |
511 Atom _ => lone_rep_fallback kk (Vect (k, R)) old_R r |
517 | Vect (k', R') => |
512 | Vect (k', R') => |
523 (map (fn arg_r => |
518 (map (fn arg_r => |
524 rel_expr_from_formula kk R (#kk_subset kk arg_r r)) |
519 rel_expr_from_formula kk R (#kk_subset kk arg_r r)) |
525 (all_singletons_for_rep R1)) |
520 (all_singletons_for_rep R1)) |
526 else |
521 else |
527 raise REP ("Nitpick_Kodkod.vect_from_rel_expr", [old_R]) |
522 raise REP ("Nitpick_Kodkod.vect_from_rel_expr", [old_R]) |
528 | Func (Unit, R2) => rel_expr_from_rel_expr kk R R2 r |
|
529 | Func (R1, R2) => |
523 | Func (R1, R2) => |
530 fold1 (#kk_product kk) |
524 fold1 (#kk_product kk) |
531 (map (fn arg_r => |
525 (map (fn arg_r => |
532 rel_expr_from_rel_expr kk R R2 |
526 rel_expr_from_rel_expr kk R R2 |
533 (kk_n_fold_join kk true R1 R2 arg_r r)) |
527 (kk_n_fold_join kk true R1 R2 arg_r r)) |
539 val R2' = case R2 of Atom _ => R2 | _ => Atom (card_of_rep R2, some_j0) |
533 val R2' = case R2 of Atom _ => R2 | _ => Atom (card_of_rep R2, some_j0) |
540 in |
534 in |
541 func_from_no_opt_rel_expr kk R1 R2 (Vect (dom_card, R2')) |
535 func_from_no_opt_rel_expr kk R1 R2 (Vect (dom_card, R2')) |
542 (vect_from_rel_expr kk dom_card R2' (Atom x) r) |
536 (vect_from_rel_expr kk dom_card R2' (Atom x) r) |
543 end |
537 end |
544 | func_from_no_opt_rel_expr kk Unit R2 old_R r = |
|
545 (case old_R of |
|
546 Vect (_, R') => rel_expr_from_rel_expr kk R2 R' r |
|
547 | Func (Unit, R2') => rel_expr_from_rel_expr kk R2 R2' r |
|
548 | Func (Atom (1, _), Formula Neut) => |
|
549 (case unopt_rep R2 of |
|
550 Atom (2, j0) => atom_from_formula kk j0 (#kk_some kk r) |
|
551 | _ => raise REP ("Nitpick_Kodkod.func_from_no_opt_rel_expr", |
|
552 [old_R, Func (Unit, R2)])) |
|
553 | Func (R1', R2') => |
|
554 rel_expr_from_rel_expr kk R2 R2' (#kk_project_seq kk r (arity_of_rep R1') |
|
555 (arity_of_rep R2')) |
|
556 | _ => raise REP ("Nitpick_Kodkod.func_from_no_opt_rel_expr", |
|
557 [old_R, Func (Unit, R2)])) |
|
558 | func_from_no_opt_rel_expr kk R1 (Formula Neut) old_R r = |
538 | func_from_no_opt_rel_expr kk R1 (Formula Neut) old_R r = |
559 (case old_R of |
539 (case old_R of |
560 Vect (k, Atom (2, j0)) => |
540 Vect (k, Atom (2, j0)) => |
561 let |
541 let |
562 val args_rs = all_singletons_for_rep R1 |
542 val args_rs = all_singletons_for_rep R1 |
576 |> rel_expr_from_rel_expr kk R1' R1 |
556 |> rel_expr_from_rel_expr kk R1' R1 |
577 val kk_xeq = (if is_one_rep R1' then #kk_subset else #kk_rel_eq) kk |
557 val kk_xeq = (if is_one_rep R1' then #kk_subset else #kk_rel_eq) kk |
578 in |
558 in |
579 #kk_comprehension kk (decls_for_atom_schema ~1 schema) (kk_xeq r1 r) |
559 #kk_comprehension kk (decls_for_atom_schema ~1 schema) (kk_xeq r1 r) |
580 end |
560 end |
581 | Func (Unit, (Atom (2, j0))) => |
|
582 #kk_rel_if kk (#kk_rel_eq kk r (KK.Atom (j0 + 1))) |
|
583 (full_rel_for_rep R1) (empty_rel_for_rep R1) |
|
584 | Func (R1', Atom (2, j0)) => |
561 | Func (R1', Atom (2, j0)) => |
585 func_from_no_opt_rel_expr kk R1 (Formula Neut) |
562 func_from_no_opt_rel_expr kk R1 (Formula Neut) |
586 (Func (R1', Formula Neut)) (#kk_join kk r (KK.Atom (j0 + 1))) |
563 (Func (R1', Formula Neut)) (#kk_join kk r (KK.Atom (j0 + 1))) |
587 | _ => raise REP ("Nitpick_Kodkod.func_from_no_opt_rel_expr", |
564 | _ => raise REP ("Nitpick_Kodkod.func_from_no_opt_rel_expr", |
588 [old_R, Func (R1, Formula Neut)])) |
565 [old_R, Func (R1, Formula Neut)])) |
613 (#kk_subset kk r2 r3) |
590 (#kk_subset kk r2 r3) |
614 end |
591 end |
615 end |
592 end |
616 | _ => raise REP ("Nitpick_Kodkod.func_from_no_opt_rel_expr", |
593 | _ => raise REP ("Nitpick_Kodkod.func_from_no_opt_rel_expr", |
617 [old_R, Func (R1, R2)])) |
594 [old_R, Func (R1, R2)])) |
618 | Func (Unit, R2') => |
|
619 let val j0 = some_j0 in |
|
620 func_from_no_opt_rel_expr kk R1 R2 (Func (Atom (1, j0), R2')) |
|
621 (#kk_product kk (KK.Atom j0) r) |
|
622 end |
|
623 | Func (R1', R2') => |
595 | Func (R1', R2') => |
624 if R1 = R1' andalso R2 = R2' then |
596 if R1 = R1' andalso R2 = R2' then |
625 r |
597 r |
626 else |
598 else |
627 let |
599 let |
1097 val dom_T = domain_type (type_of u1) |
1069 val dom_T = domain_type (type_of u1) |
1098 val R1 = rep_of u1 |
1070 val R1 = rep_of u1 |
1099 val R2 = rep_of u2 |
1071 val R2 = rep_of u2 |
1100 val (dom_R, ran_R) = |
1072 val (dom_R, ran_R) = |
1101 case min_rep R1 R2 of |
1073 case min_rep R1 R2 of |
1102 Func (Unit, R') => |
1074 Func Rp => Rp |
1103 (Atom (1, offset_of_type ofs dom_T), R') |
|
1104 | Func Rp => Rp |
|
1105 | R => (Atom (card_of_domain_from_rep 2 R, |
1075 | R => (Atom (card_of_domain_from_rep 2 R, |
1106 offset_of_type ofs dom_T), |
1076 offset_of_type ofs dom_T), |
1107 if is_opt_rep R then Opt bool_atom_R else Formula Neut) |
1077 if is_opt_rep R then Opt bool_atom_R else Formula Neut) |
1108 val set_R = Func (dom_R, ran_R) |
1078 val set_R = Func (dom_R, ran_R) |
1109 in |
1079 in |
1124 val widen2 = (polar = Neg andalso is_opt_rep R2) |
1094 val widen2 = (polar = Neg andalso is_opt_rep R2) |
1125 in kk_subset (set_to_r widen1 u1) (set_to_r widen2 u2) end |
1095 in kk_subset (set_to_r widen1 u1) (set_to_r widen2 u2) end |
1126 end |
1096 end |
1127 | Op2 (DefEq, _, _, u1, u2) => |
1097 | Op2 (DefEq, _, _, u1, u2) => |
1128 (case min_rep (rep_of u1) (rep_of u2) of |
1098 (case min_rep (rep_of u1) (rep_of u2) of |
1129 Unit => KK.True |
1099 Formula polar => |
1130 | Formula polar => |
|
1131 kk_iff (to_f_with_polarity polar u1) (to_f_with_polarity polar u2) |
1100 kk_iff (to_f_with_polarity polar u1) (to_f_with_polarity polar u2) |
1132 | min_R => |
1101 | min_R => |
1133 let |
1102 let |
1134 fun args (Op2 (Apply, _, _, u1, u2)) = u2 :: args u1 |
1103 fun args (Op2 (Apply, _, _, u1, u2)) = u2 :: args u1 |
1135 | args (Tuple (_, _, us)) = us |
1104 | args (Tuple (_, _, us)) = us |
1143 else |
1112 else |
1144 kk_subset (to_rep min_R u1) (to_rep min_R u2) |
1113 kk_subset (to_rep min_R u1) (to_rep min_R u2) |
1145 end) |
1114 end) |
1146 | Op2 (Eq, _, _, u1, u2) => |
1115 | Op2 (Eq, _, _, u1, u2) => |
1147 (case min_rep (rep_of u1) (rep_of u2) of |
1116 (case min_rep (rep_of u1) (rep_of u2) of |
1148 Unit => KK.True |
1117 Formula polar => |
1149 | Formula polar => |
|
1150 kk_iff (to_f_with_polarity polar u1) (to_f_with_polarity polar u2) |
1118 kk_iff (to_f_with_polarity polar u1) (to_f_with_polarity polar u2) |
1151 | min_R => |
1119 | min_R => |
1152 if is_opt_rep min_R then |
1120 if is_opt_rep min_R then |
1153 if polar = Neut then |
1121 if polar = Neut then |
1154 (* continuation of hackish optimization *) |
1122 (* continuation of hackish optimization *) |
1424 else |
1392 else |
1425 let val R' = rep_to_binary_rel_rep ofs (type_of u1) (rep_of u1) in |
1393 let val R' = rep_to_binary_rel_rep ofs (type_of u1) (rep_of u1) in |
1426 rel_expr_from_rel_expr kk R R' (kk_closure (to_rep R' u1)) |
1394 rel_expr_from_rel_expr kk R R' (kk_closure (to_rep R' u1)) |
1427 end |
1395 end |
1428 | Op1 (SingletonSet, _, Func (R1, Opt _), Cst (Unrep, _, _)) => |
1396 | Op1 (SingletonSet, _, Func (R1, Opt _), Cst (Unrep, _, _)) => |
1429 (if R1 = Unit then I else kk_product (full_rel_for_rep R1)) false_atom |
1397 kk_product (full_rel_for_rep R1) false_atom |
1430 | Op1 (SingletonSet, _, R, u1) => |
1398 | Op1 (SingletonSet, _, R, u1) => |
1431 (case R of |
1399 (case R of |
1432 Func (R1, Formula Neut) => to_rep R1 u1 |
1400 Func (R1, Formula Neut) => to_rep R1 u1 |
1433 | Func (Unit, Opt R) => to_guard [u1] R true_atom |
|
1434 | Func (R1, Opt _) => |
1401 | Func (R1, Opt _) => |
1435 single_rel_rel_let kk |
1402 single_rel_rel_let kk |
1436 (fn r => kk_rel_if (kk_no r) (empty_rel_for_rep R) |
1403 (fn r => kk_rel_if (kk_no r) (empty_rel_for_rep R) |
1437 (rel_expr_to_func kk R1 bool_atom_R |
1404 (rel_expr_to_func kk R1 bool_atom_R |
1438 (Func (R1, Formula Neut)) r)) |
1405 (Func (R1, Formula Neut)) r)) |
1674 | Tuple (_, R, us) => |
1641 | Tuple (_, R, us) => |
1675 (case unopt_rep R of |
1642 (case unopt_rep R of |
1676 Struct Rs => to_product Rs us |
1643 Struct Rs => to_product Rs us |
1677 | Vect (k, R) => to_product (replicate k R) us |
1644 | Vect (k, R) => to_product (replicate k R) us |
1678 | Atom (1, j0) => |
1645 | Atom (1, j0) => |
1679 (case filter (not_equal Unit o rep_of) us of |
1646 kk_rel_if (kk_some (fold1 kk_product (map to_r us))) |
1680 [] => KK.Atom j0 |
1647 (KK.Atom j0) KK.None |
1681 | us' => kk_rel_if (kk_some (fold1 kk_product (map to_r us'))) |
|
1682 (KK.Atom j0) KK.None) |
|
1683 | _ => raise NUT ("Nitpick_Kodkod.to_r (Tuple)", [u])) |
1648 | _ => raise NUT ("Nitpick_Kodkod.to_r (Tuple)", [u])) |
1684 | Construct ([u'], _, _, []) => to_r u' |
1649 | Construct ([u'], _, _, []) => to_r u' |
1685 | Construct (discr_u :: sel_us, _, _, arg_us) => |
1650 | Construct (discr_u :: sel_us, _, _, arg_us) => |
1686 let |
1651 let |
1687 val set_rs = |
1652 val set_rs = |
1713 KK.AssignRelReg ((arity_of_rep R, j), to_r u) |
1678 KK.AssignRelReg ((arity_of_rep R, j), to_r u) |
1714 | to_expr_assign u1 _ = raise NUT ("Nitpick_Kodkod.to_expr_assign", [u1]) |
1679 | to_expr_assign u1 _ = raise NUT ("Nitpick_Kodkod.to_expr_assign", [u1]) |
1715 and to_atom (x as (k, j0)) u = |
1680 and to_atom (x as (k, j0)) u = |
1716 case rep_of u of |
1681 case rep_of u of |
1717 Formula _ => atom_from_formula kk j0 (to_f u) |
1682 Formula _ => atom_from_formula kk j0 (to_f u) |
1718 | Unit => if k = 1 then KK.Atom j0 |
|
1719 else raise NUT ("Nitpick_Kodkod.to_atom", [u]) |
|
1720 | R => atom_from_rel_expr kk x R (to_r u) |
1683 | R => atom_from_rel_expr kk x R (to_r u) |
1721 and to_struct Rs u = |
1684 and to_struct Rs u = struct_from_rel_expr kk Rs (rep_of u) (to_r u) |
1722 case rep_of u of |
1685 and to_vect k R u = vect_from_rel_expr kk k R (rep_of u) (to_r u) |
1723 Unit => full_rel_for_rep (Struct Rs) |
1686 and to_func R1 R2 u = rel_expr_to_func kk R1 R2 (rep_of u) (to_r u) |
1724 | R' => struct_from_rel_expr kk Rs R' (to_r u) |
|
1725 and to_vect k R u = |
|
1726 case rep_of u of |
|
1727 Unit => full_rel_for_rep (Vect (k, R)) |
|
1728 | R' => vect_from_rel_expr kk k R R' (to_r u) |
|
1729 and to_func R1 R2 u = |
|
1730 case rep_of u of |
|
1731 Unit => full_rel_for_rep (Func (R1, R2)) |
|
1732 | R' => rel_expr_to_func kk R1 R2 R' (to_r u) |
|
1733 and to_opt R u = |
1687 and to_opt R u = |
1734 let val old_R = rep_of u in |
1688 let val old_R = rep_of u in |
1735 if is_opt_rep old_R then |
1689 if is_opt_rep old_R then |
1736 rel_expr_from_rel_expr kk (Opt R) old_R (to_r u) |
1690 rel_expr_from_rel_expr kk (Opt R) old_R (to_r u) |
1737 else |
1691 else |
1762 else kk_rel_if (fold1 kk_or guard_fs) (empty_rel_for_rep R) r |
1716 else kk_rel_if (fold1 kk_or guard_fs) (empty_rel_for_rep R) r |
1763 end |
1717 end |
1764 and to_project new_R old_R r j0 = |
1718 and to_project new_R old_R r j0 = |
1765 rel_expr_from_rel_expr kk new_R old_R |
1719 rel_expr_from_rel_expr kk new_R old_R |
1766 (kk_project_seq r j0 (arity_of_rep old_R)) |
1720 (kk_project_seq r j0 (arity_of_rep old_R)) |
1767 and to_product Rs us = |
1721 and to_product Rs us = fold1 kk_product (map (uncurry to_opt) (Rs ~~ us)) |
1768 case map (uncurry to_opt) (filter (not_equal Unit o fst) (Rs ~~ us)) of |
|
1769 [] => raise REP ("Nitpick_Kodkod.to_product", Rs) |
|
1770 | rs => fold1 kk_product rs |
|
1771 and to_nth_pair_sel n res_T res_R u = |
1722 and to_nth_pair_sel n res_T res_R u = |
1772 case u of |
1723 case u of |
1773 Tuple (_, _, us) => to_rep res_R (nth us n) |
1724 Tuple (_, _, us) => to_rep res_R (nth us n) |
1774 | _ => let |
1725 | _ => let |
1775 val R = rep_of u |
1726 val R = rep_of u |
1787 [Atom (a_card, offset_of_type ofs a_T), |
1738 [Atom (a_card, offset_of_type ofs a_T), |
1788 Atom (b_card, offset_of_type ofs b_T)] |
1739 Atom (b_card, offset_of_type ofs b_T)] |
1789 end |
1740 end |
1790 val nth_R = nth Rs n |
1741 val nth_R = nth Rs n |
1791 val j0 = if n = 0 then 0 else arity_of_rep (hd Rs) |
1742 val j0 = if n = 0 then 0 else arity_of_rep (hd Rs) |
1792 in |
1743 in to_project res_R nth_R (to_rep (Opt (Struct Rs)) u) j0 end |
1793 case arity_of_rep nth_R of |
|
1794 0 => to_guard [u] res_R |
|
1795 (to_rep res_R (Cst (Unity, res_T, Unit))) |
|
1796 | _ => to_project res_R nth_R (to_rep (Opt (Struct Rs)) u) j0 |
|
1797 end |
|
1798 and to_set_bool_op connective set_oper u1 u2 = |
1744 and to_set_bool_op connective set_oper u1 u2 = |
1799 let |
1745 let |
1800 val min_R = min_rep (rep_of u1) (rep_of u2) |
1746 val min_R = min_rep (rep_of u1) (rep_of u2) |
1801 val r1 = to_rep min_R u1 |
1747 val r1 = to_rep min_R u1 |
1802 val r2 = to_rep min_R u2 |
1748 val r2 = to_rep min_R u2 |
1803 in |
1749 in |
1804 case min_R of |
1750 case min_R of |
1805 Vect (k, Atom _) => kk_vect_set_bool_op connective k r1 r2 |
1751 Vect (k, Atom _) => kk_vect_set_bool_op connective k r1 r2 |
1806 | Func (_, Formula Neut) => set_oper r1 r2 |
1752 | Func (_, Formula Neut) => set_oper r1 r2 |
1807 | Func (Unit, Atom (2, j0)) => |
|
1808 connective (formula_from_atom j0 r1) (formula_from_atom j0 r2) |
|
1809 | Func (_, Atom _) => set_oper (kk_join r1 true_atom) |
1753 | Func (_, Atom _) => set_oper (kk_join r1 true_atom) |
1810 (kk_join r2 true_atom) |
1754 (kk_join r2 true_atom) |
1811 | _ => raise REP ("Nitpick_Kodkod.to_set_bool_op", [min_R]) |
1755 | _ => raise REP ("Nitpick_Kodkod.to_set_bool_op", [min_R]) |
1812 end |
1756 end |
1813 and to_bit_word_unary_op T R oper = |
1757 and to_bit_word_unary_op T R oper = |
1841 end |
1785 end |
1842 and to_apply (R as Formula _) func_u arg_u = |
1786 and to_apply (R as Formula _) func_u arg_u = |
1843 raise REP ("Nitpick_Kodkod.to_apply", [R]) |
1787 raise REP ("Nitpick_Kodkod.to_apply", [R]) |
1844 | to_apply res_R func_u arg_u = |
1788 | to_apply res_R func_u arg_u = |
1845 case unopt_rep (rep_of func_u) of |
1789 case unopt_rep (rep_of func_u) of |
1846 Unit => |
1790 Atom (1, j0) => |
1847 let val j0 = offset_of_type ofs (type_of func_u) in |
|
1848 to_guard [arg_u] res_R |
|
1849 (rel_expr_from_rel_expr kk res_R (Atom (1, j0)) (KK.Atom j0)) |
|
1850 end |
|
1851 | Atom (1, j0) => |
|
1852 to_guard [arg_u] res_R |
1791 to_guard [arg_u] res_R |
1853 (rel_expr_from_rel_expr kk res_R (Atom (1, j0)) (to_r func_u)) |
1792 (rel_expr_from_rel_expr kk res_R (Atom (1, j0)) (to_r func_u)) |
1854 | Atom (k, _) => |
1793 | Atom (k, _) => |
1855 let |
1794 let |
1856 val dom_card = card_of_rep (rep_of arg_u) |
1795 val dom_card = card_of_rep (rep_of arg_u) |
1865 (rel_expr_from_rel_expr kk res_R R' (to_r func_u)) |
1804 (rel_expr_from_rel_expr kk res_R R' (to_r func_u)) |
1866 | Vect (k, R') => to_apply_vect k R' res_R (to_r func_u) arg_u |
1805 | Vect (k, R') => to_apply_vect k R' res_R (to_r func_u) arg_u |
1867 | Func (R, Formula Neut) => |
1806 | Func (R, Formula Neut) => |
1868 to_guard [arg_u] res_R (rel_expr_from_formula kk res_R |
1807 to_guard [arg_u] res_R (rel_expr_from_formula kk res_R |
1869 (kk_subset (to_opt R arg_u) (to_r func_u))) |
1808 (kk_subset (to_opt R arg_u) (to_r func_u))) |
1870 | Func (Unit, R2) => |
|
1871 to_guard [arg_u] res_R |
|
1872 (rel_expr_from_rel_expr kk res_R R2 (to_r func_u)) |
|
1873 | Func (R1, R2) => |
1809 | Func (R1, R2) => |
1874 rel_expr_from_rel_expr kk res_R R2 |
1810 rel_expr_from_rel_expr kk res_R R2 |
1875 (kk_n_fold_join kk true R1 R2 (to_opt R1 arg_u) (to_r func_u)) |
1811 (kk_n_fold_join kk true R1 R2 (to_opt R1 arg_u) (to_r func_u)) |
1876 |> body_rep R2 = Formula Neut ? to_guard [arg_u] res_R |
1812 |> body_rep R2 = Formula Neut ? to_guard [arg_u] res_R |
1877 | _ => raise NUT ("Nitpick_Kodkod.to_apply", [func_u]) |
1813 | _ => raise NUT ("Nitpick_Kodkod.to_apply", [func_u]) |