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 }