作为家庭作业,我必须在Alloy中定义堆数据结构。
我已经提出了这些规则
问题是双重的
A)我不确定这些规则是否足够,或者是否有更好的方法来解决这个问题。 (我想我可以通过让节点由索引和值组成并将堆中数组算法转换为Alloy来解决这一问题,但这似乎相当不优雅。)
B)我无法实施其中一些规则。
我已经实施了规则1,2,3,4,5,6,7,8和9.至少我认为我做了,生成的图表与我的期望并不矛盾。
我不知道如何实施最后的2。
此外,我到目前为止的代码:
open util/ordering [Key] as KO
open util/ordering [Level] as LO
sig Key{}
sig Level{}
sig Node {
key: one Key,
level: one Level,
father: lone Node,
left_brother: lone Node,
right_brother: lone Node,
left_son: lone Node,
right_son: lone Node
}
// There's exactly one root
fact {
one n : Node | n.father = none
}
// Every key has to belong to some node
fact {
all k : Key | some n:Node | n.key = k
}
fact {
all n : Node | (n.left_son != none && n.right_son != none) => #(KO/nexts[n.key] & (n.left_son.key + n.right_son.key)) = 2
}
// Son's father's son shall be Son etc
fact {
all n : Node | all m : Node | (n.left_son = m) => m.father = n
}
fact {
all n : Node | all m : Node | (n.right_son = m) => m.father = n
}
fact {
all n : Node | all m : Node | (m.father = n) => (n.left_son = m || n.right_son = m)
}
// Is this redundant?
fact {
all n : Node | all m : Node | (n.left_brother = m) => (m.right_brother = n)
}
fact {
all n : Node | all m : Node | (n.right_brother = m) => (m.left_brother = n)
}
// If a node has right-son, it must have a left-son.
fact {
all n : Node | (n.right_son != none) => (n.left_son != none)
}
// node having left son and left brother means that his left brother has a right son
fact {
all n: Node | (n.left_son != none && n.left_brother != none) => (n.left_brother.right_son != none)
}
// nodes father must be a level higher.
fact {
all n : Node | (n.father != none) => (LO/prev[n.level] = n.father.level)
}
// FIXME: this is wrong: There needs to be difference of 2 levels, not just a single level.
fact {
all n : Node | all m : Node | (LO/prevs[m.level] & n.level = n.level) => (n.left_son != none && n.right_son != none)
}
// TODO: If 2 nodes are in the same level, then they must be in left-brother* or right-brother* relation
// ????
// No node can be its own father
fact {
all n : Node | n.father != n
}
// No node can be in transitive closure over its ancestors
fact {
no n : Node | n in n.^father
}
// No node cannot be its own brother, son, etc...
fact {
all n: Node | n.left_brother != n
}
// Nor in its transitive closure
fact {
no n: Node | n in n.^left_brother
}
fact {
all n: Node | n.right_brother != n
}
fact {
no n: Node | n in n.^right_brother
}
fact {
all n: Node | n.left_brother != n
}
fact {
no n: Node | n in n.^left_brother
}
fact {
all n: Node | n.right_son != n
}
fact {
no n: Node | n in n.^right_son
}
fact {
all n: Node | n.left_son != n
}
fact {
no n: Node | n in n.^left_son
}
// All node relatives have to be distinct
fact {
all n: Node | n.left_son & n.right_son = none && n.left_brother & n.right_brother = none && (n.left_brother + n.right_brother) & (n.left_son + n.right_son) = none
&& (n.right_son + n.left_son + n.left_brother + n.right_brother) & n.father = none
}
run{}
答案 0 :(得分:0)
对于10.
的内容all m : Node | some father.father.m implies some m.left and m.right
会起作用,相当于
fact {
all m, n : Node | (n.father.father != none && n.father.father.level = m.level) => (m.left_son != none && m.right_son != none)
}
对于11.,你可以从文本定义中直接表达它(当然,使用适当的运算符,即传递闭包)。
作为一般性建议,尽量不要提出有关家庭作业问题的直接问题(见discussion)。由于这个答案很晚,我觉得尝试给你一些提示是没问题的。