-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunique.go
65 lines (59 loc) · 1.66 KB
/
unique.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Copyright (c) 2024 Silvano DAL ZILIO
//
// GNU Affero GPL v3
package nets
import (
"bytes"
"encoding/binary"
"fmt"
"math"
"unique"
)
// Handle is a unique identifier for a Marking. Basically this is the canonical,
// interned version (using go unique package) of a string representation of a
// Marking.
type Handle unique.Handle[string]
// Value returns a copy of the string value that produced the Handle.
func (h Handle) Value() string {
return unique.Handle[string](h).Value()
}
// Unique returns a unique Handle from a marking. It only accepts positive
// markings where multiplicities can be cast into a uint32 value.
func (m Marking) Unique() (Handle, error) {
var buf bytes.Buffer
buf.Grow(8 * len(m))
arr := make([]byte, 4)
//
// we assume that a place index is never greater than MaxInt32, which means
// more than 2.147 billion places in the net !
//
for _, v := range m {
if v.Mult < 0 {
return Handle(unique.Make("")), fmt.Errorf("negative multiplicity")
}
if v.Mult >= math.MaxInt32 {
return Handle(unique.Make("")), fmt.Errorf("multiplicity over MaxInt32")
}
binary.BigEndian.PutUint32(arr, uint32(v.Pl))
buf.Write(arr)
binary.BigEndian.PutUint32(arr, uint32(v.Mult))
buf.Write(arr)
}
return Handle(unique.Make(buf.String())), nil
}
// Marking returns the marking associated with a marking Handle
func (mk Handle) Marking() Marking {
m := Marking{}
// We use the fact that places occuring in markings are in increasing
// order
s := []byte(mk.Value())
a := Atom{}
i := 0
for i < len(s) {
a.Pl = int(binary.BigEndian.Uint32(s[i : i+4]))
a.Mult = int(binary.BigEndian.Uint32(s[i+4 : i+8]))
m = append(m, a)
i += 8
}
return m
}