Semantic Diffing of Formal Policies with Anti-Unification
When large language models generate formalized policies for the same requirement twice, textual differences mark numerous meaningless syntactic changes, while true differences that alter authorization behavior (such as And becoming Or) may be drowned out. An AWS Machine Learning blog introduces an open-source engine that uses anti-unification to compute semantic diffs on equivalence graphs, presenting shared structure only once and marking every genuine divergence as a reviewable Variants node.
When an automated policy generation process translates the same natural language requirement into two formal policies, the first question facing reviewers is not which one is correct, but where they actually differ. Textual diff tools fail systematically here: swapping the order of two conjuncts, rewriting an external destination as non-internal, or replacing one predicate with an equivalent one will flag many lines as changed, while the real difference in authorization behavior—such as changing And to Or—may be lost in the noise.
The AWS Machine Learning blog introduces semi-persistent, an open-source engine that computes semantic diffs of formal policies using anti-unification. Anti-unification stems from Plotkin's classic 1970 work, aiming to find the most specific common pattern between two expressions. The engine runs over an e-graph, which tracks expressions known to be equal; users inform the engine which syntactic changes do not alter meaning by declaring algebraic laws (such as associativity, commutativity, and idempotence of conjunction) and domain rules (such as equating an external destination with a non-internal one).
The engine outputs a single term where shared structure appears only once, and each divergence is marked as a Variants node containing the complete subtrees of both candidates. Selecting the first child of each Variants node reconstructs candidate A, while selecting the second child reconstructs candidate B. This means the anti-unification result is a lossless merge of the two inputs: it does not discard information but folds identical parts together and retains and locates differing parts.