抽象によるソフトウェア設計 付録A 練習問題 その21
付録A.5 の小さなケーススタディの鉄道のスイッチングです。
- A.5.2 (c), (d), (e), (f)
open util/ordering [TrainState] sig Segment { next: lone Segment, overlaps: some Segment } sig Train {} sig TrainState { on: Train -> one Segment, occupied: Train -> some Segment } { all t: Train |{ t.occupied = t.on.^overlaps } all disj t1, t2: Train |{ no t1.occupied & t2.occupied } } sig GateState { closed: set Segment } fact { all s: Segment { s != s.next } } fact { (Segment <: iden) in overlaps // 反射的 ~overlaps in overlaps // 対称的 } pred transit (ts, ts': TrainState, g: GateState, t: some Train) { let m = { x: t | not ts.on[x].next in g.closed } { ts'.on = ts.on - (m -> ts.on[m]) + (m -> ts.on[m].next) } } run { #overlaps > #Segment all ts: TrainState - last { let ts' = ts.next { some t: Train | one g: GateState { transit [ts, ts', g, t] } } } }
-
- TrainState の制約として overlaps で重複している Segment のなかには1つしか Train が存在できないようにしています (f)
- util/ordering を使って TrainState を時系列で並べるようにして、その間の Train の移動を記述するようにしています (c), (d)
- GateStatus を導入して侵入できない Segment を指定するようにしています (e)
次はこの GateState を適切に指示するポリシーを作らないといけないのですが、なかなか難しいですね。