如下面的代码所示,有没有办法为表达式NP + NF2 + NF1 + NT + NR
和AnonActive + Aactive + AsetTurn + Astart + Acrit + Acheck + APF2 + APF1 + ATP + ATR + AF2R + AF1R
制作宏,以便我可以稍后通过名称引用它们而不是直接写出表达式?< / p>
sig NP{}
sig NF2{}
sig NF1{}
sig NT{}
sig NR{}
sig AnonActive{src:one NP, trg:one NP}
sig Aactive{src:one NP, trg:one NP}
sig AsetTurn{src:one NP, trg:one NP}
sig Astart{src:one NP, trg:one NP}
sig Acrit{src:one NP, trg:one NP}
sig Acheck{src:one NP, trg:one NP}
sig APF2{src:one NP, trg:one NF2}
sig APF1{src:one NP, trg:one NF1}
sig ATP{src:one NT, trg:one NP}
sig ATR{src:one NT, trg:one NR}
sig AF2R{src:one NF2, trg:one NR}
sig AF1R{src:one NF1, trg:one NR}
sig Graph{nodes:set NP+NF2+NF1+NT+NR,
arrows:set AnonActive + Aactive + AsetTurn + Astart
+ Acrit + Acheck + APF2 + APF1 + ATP + ATR
+ AF2R + AF1R}
答案 0 :(得分:1)
一种简单的方法是声明抽象签名Node
和Arrow
,并将每个现有签名声明为扩展其中一个或另一个。
abstract sig Node {}
sig NP extends Node {}
sig NF2 extends Node {}
...
由于所有箭头都具有相同的关系,因此可以在Arrow sig中声明关系;可以使用签名事实给出对源和目标允许的节点类型的限制,例如:
abstract sig Arrow {
src: one Node,
trg: one Node
}
sig AnonActive extends Arrow {}{
one + trg in NP
}
...
sig AF1R extends Arrow {}{
src in NF1
trg in NR
}
现在Graph的声明很简单(至少对某些人而言,可能更清楚一点):
sig Graph {
nodes: set Node,
arrows: set Arrow
}
另一种方法(我认为在所示情况下不太好,但在第一种方法无法应用的情况下很有用)将是用适当的名称定义函数:
fun Node : set univ {
NP + NF2 + NF1 + NT + NR
}
fun Arrow : set univ {
AnonActive + Aactive + AsetTurn + Astart
+ Acrit + Acheck + APF2 + APF1 + ATP + ATR
+ AF2R + AF1R
}
N.B。我没有检查这些语法错误...