Несвязный союз двух подписей в Alloy
Я уже спрашивал о декартовом произведении и непересекающемся союзе в Alloy здесь. Там я рассматривал множества как унарные определенные предикаты.
Что если я просто хочу разделить объединение двух простых подписей в Alloy.
Предположим, у меня есть следующие подписи:
sig A {}
sig B {}
Я хотел бы определить отношение от А до B Û B
где я использовал Û
для несвязанного союза. Возможно ли это прямо в сплаве?
1 ответ
Я могу думать о двух подходах. (Но я понимаю, перечитывая ваш вопрос, я понятия не имею, что означает ваш последний абзац. Так что, возможно, это все не имеет отношения к вашим целям.)
Во-первых: дизъюнктное объединение помечает каждый элемент флагом, чтобы вы знали, из какого родительского набора он получен, и чтобы ни один элемент в непересекающемся объединении не был в обоих родительских наборах. Если целью упражнения является обеспечение того, чтобы вы знали, из какого родительского набора произошел каждый член непересекающегося объединения, и чтобы ни один из членов непересекающегося объединения не происходил из более чем одного родительского набора, то в этом случае нормальное объединение кажется делать то, что вам нужно. В вашем примере сигнатуры A и B уже не пересекаются, и всегда можно сказать, находится ли данный атом в A или в B. Поэтому первый подход заключается в использовании выражения A + B
,
Второе: если A + B
не будет, по причинам, не указанным в вопросе, и вы действительно хотите набор пар, а затем определите этот набор пар. В каждой паре либо первый элемент принадлежит A, а второй элемент равен 1 (или некоторому другому флажку), либо первый элемент относится к B, а второй элемент равен 2 (или некоторому другому признаку).
Один из способов написать это будет:
{v : X + Y, n : Int | (v in X and n = 1) or (v in Y and n = 2) }
Другой эквивалентный способ будет:
{x : X, y : Int | y = 1}
+
{x : Y, y : Int | y = 2}
Третий способ еще проще:
{v : X, n : 1} + {v : Y, n : 2}
И еще проще:
(X -> 1) + (Y -> 2)
Как и любое выражение, это может быть упаковано в функцию:
fun du[Left, Right : set univ] : (Left + Right) -> Int {
(Left -> 1) + (Right -> 2)
}
И тогда непересекающийся союз А и В может быть записан du[A, B]
,
Я повторяю свой совет, чтобы потратить некоторое время на изучение понимания.