///|
fn valid_name(name : String) -> Bool {
name.code_units().all(fn(c) { c >= 32 && c != 65534 && c != 65535 })
}
///|
/// Verify model invariants without modifying the net.
pub fn PetriNet::validate(self : PetriNet) -> Result[Unit, Array[PetriError]] {
let errors : Array[PetriError] = []
if self.initial.length() != self.places.length() {
errors.push(InvalidMarking)
}
let names : Map[String, Bool] = Map([])
for name in self.places {
if name.trim() == "" {
errors.push(EmptyName)
}
if !valid_name(name) {
errors.push(InvalidName)
}
if names.contains(name) {
errors.push(DuplicateName(name))
}
names[name] = true
}
for tokens in self.initial {
if tokens < 0 {
errors.push(NegativeTokens)
}
}
let transitions : Map[String, Bool] = Map([])
for t in 0..= self.places.length() {
errors.push(InvalidPlace)
}
if arc.transition != t {
errors.push(InvalidTransition)
}
if arc.weight <= 0 {
errors.push(InvalidWeight)
}
if seen.contains(arc.place) {
errors.push(InvalidWeight)
}
seen[arc.place] = true
}
}
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
///|
/// Resolve a transition's unique domain name, not its PNML serialization ID.
pub fn PetriNet::find_transition(self : PetriNet, name : String) -> Int? {
for t in 0.. Int? {
self.pnml_transition_ids.get(id)
}