lib/accy/src/choir/shape/fingerprint.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const choir = @import("choir");
2
3 const expression = @import("expression.zig");
4 const fact = @import("fact.zig");
5 const family_mod = @import("family.zig");
6 const tensor = @import("tensor.zig");
7
8 pub fn family(value: family_mod.Family) choir.product.incremental.Fingerprint {
9 var builder = choir.product.incremental.FingerprintBuilder{};
10 builder.updateBytes("accy.choir.shape.family");
11 builder.updateBytes(value.name);
12 builder.updateUsize(value.symbols.len);
13 for (value.symbols) |symbol| builder.updateBytes(symbol.name);
14 builder.updateUsize(value.tensors.len);
15 for (value.tensors) |tensor_value| hashTensor(&builder, tensor_value);
16 builder.updateUsize(value.facts.len);
17 for (value.facts) |fact_value| hashFact(&builder, fact_value);
18 return builder.finish();
19 }
20
21 fn hashTensor(builder: *choir.product.incremental.FingerprintBuilder, value: tensor.Tensor) void {
22 builder.updateBytes(value.name);
23 builder.updateUsize(value.extents.len);
24 for (value.extents) |extent| hashExpression(builder, extent);
25 }
26
27 fn hashFact(builder: *choir.product.incremental.FingerprintBuilder, value: fact.Fact) void {
28 builder.updateEnumTag(value.mode);
29 builder.updateEnumTag(value.predicate);
30 switch (value.predicate) {
31 .equal => |equal| {
32 hashExpression(builder, equal.lhs);
33 hashExpression(builder, equal.rhs);
34 },
35 .bound => |bound| {
36 hashExpression(builder, bound.value);
37 hashBounds(builder, bound.bounds);
38 },
39 .divisible => |divisible| {
40 hashExpression(builder, divisible.value);
41 builder.updateU64(divisible.divisor);
42 },
43 }
44 }
45
46 fn hashExpression(builder: *choir.product.incremental.FingerprintBuilder, value: expression.Expression) void {
47 builder.updateI64(value.constant);
48 builder.updateUsize(value.terms.len);
49 for (value.terms) |term| {
50 builder.updateU32(term.symbol);
51 builder.updateI64(term.coefficient);
52 }
53 }
54
55 fn hashBounds(builder: *choir.product.incremental.FingerprintBuilder, value: fact.Bounds) void {
56 builder.updateOptionalU64(value.min);
57 builder.updateOptionalU64(value.opt);
58 builder.updateOptionalU64(value.max);
59 }