Summary
tensor_inner_product_to_scalar (include/numsim_cas/tensor_to_scalar/tensor_inner_product_to_scalar.h) stores contraction index sequences but has no update_hash_value/operator== override — it inherits binary_op's hash (id+lhs+rhs only) and binary_op::operator== (core/binary_op.h:162-166, children only). Distinct contractions compare equal (reproduced at 0f6c0b9, non-symmetric A, B):
dot_product(A, {1,2}, B, {1,2}) == dot_product(A, {1,2}, B, {2,1}) // true — A:B vs A:Bᵀ
// their sum → 2*dot(A,{1,2},B,{2,1}) — WRONG
// their diff → 0 — WRONG
This is the same bug class as #266 (fixed there for inner_product_wrapper; tensor_to_scalar_eigenvalue.h:42-48 explicitly mirrors that fix — this node was missed) and the permute_indices_wrapper issue (#342).
Severity: critical (silent wrong algebra for any permuted contraction). The evaluator half of this node's problems is tracked separately (evaluator ignores the sequences).
Fix
Add an update_hash_value() override that hash_combines m_lhs_indices/m_rhs_indices (copy inner_product_wrapper.h:59-67), and a member operator== comparing both sequences in addition to the children.
Tests (lock-in)
TEST(T2sInnerProductIdentity, IndexSequencesDistinguish) {
auto [A] = make_tensor_variable(std::tuple{"A", 3, 2});
auto [B] = make_tensor_variable(std::tuple{"B", 3, 2});
auto ab = dot_product(A, sequence{1,2}, B, sequence{1,2});
auto abt = dot_product(A, sequence{1,2}, B, sequence{2,1});
EXPECT_FALSE(*ab == *abt);
EXPECT_NE(ab.get().hash_value(), abt.get().hash_value());
EXPECT_NE(to_string(ab - abt), "0");
// identical sequences still fold
auto ab2 = dot_product(A, sequence{1,2}, B, sequence{1,2});
EXPECT_EQ(to_string(ab - ab2), "0");
}
Summary
tensor_inner_product_to_scalar(include/numsim_cas/tensor_to_scalar/tensor_inner_product_to_scalar.h) stores contraction index sequences but has noupdate_hash_value/operator==override — it inheritsbinary_op's hash (id+lhs+rhs only) andbinary_op::operator==(core/binary_op.h:162-166, children only). Distinct contractions compare equal (reproduced at 0f6c0b9, non-symmetric A, B):This is the same bug class as #266 (fixed there for
inner_product_wrapper;tensor_to_scalar_eigenvalue.h:42-48explicitly mirrors that fix — this node was missed) and the permute_indices_wrapper issue (#342).Severity: critical (silent wrong algebra for any permuted contraction). The evaluator half of this node's problems is tracked separately (evaluator ignores the sequences).
Fix
Add an
update_hash_value()override thathash_combinesm_lhs_indices/m_rhs_indices(copyinner_product_wrapper.h:59-67), and a memberoperator==comparing both sequences in addition to the children.Tests (lock-in)