如何在Alloy(Homework)中定义堆数据结构

时间:2015-12-01 19:42:25

标签: alloy

作为家庭作业,我必须在Alloy中定义堆数据结构。

我已经提出了这些规则

  1. 一个节点最多可以有1个父亲,左子,右子,左兄弟和右兄弟。它也只有1个值和1个级别(就像堆中的深度一样)。
  2. 如果节点有左子,则该节点可以拥有右子。
  3. 一个节点不能对其任何关系(父亲,左子,右子,左兄弟,右兄弟)进行传递性封闭。
  4. 关系必须指向不同的节点。
  5. 节点具有值,值必须属于节点。
  6. 节点的值必须小于节点的儿子的值。值。
  7. 如果一个节点有左子而不是左兄弟,那么其父亲最右边的兄弟就有一个右子。
  8. Node是它的左兄弟的右兄弟,所以它的所有关系都是如此。
  9. 节点的父级别比节点级别低一级。
  10. 如果存在级别为2的节点,则具有该级别的所有节点必须同时具有两个子级。
  11. 对于任何2个节点m,n具有相同的级别,m必须在n的左兄弟的传递闭包中,或者在右兄弟的传递闭包中。
  12. 问题是双重的

    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{}
    

1 个答案:

答案 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)。由于这个答案很晚,我觉得尝试给你一些提示是没问题的。