Operations

The mechanism by which statements are derived is furnished by operations. Roughly speaking, with few exceptions, an operation deduces a statement from one or more existing statements according to some relation that must be satisfied between these statements. For example, if Equal(ak1, ak2) holds true, then the operation SymmetricEq applied to this statement yields Equal(ak2, ak1).

More precisely, an operation is a code (or, in the frontend, string identifier) followed by 0 or more arguments. These arguments may consist of up to three statements, up to one key-value pair and up to one Merkle proof.

The following table summarises the natively-supported operations:

CodeIdentifierArgsConditionOutput
0NoneNone
1NewEntry1(key, value)ValueOf(ak, value), where ak has key key and origin ID 1
2CopyStatements
3EqualFromEntriess1, s2s1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), value1 = value2Equal(ak1, ak2)
4NotEqualFromEntriess1, s2s1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), value1 != value2NotEqual(ak1, ak2)
5LtEqFromEntriess1, s2s1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), value1 <= value2LtEq(ak1, ak2)
6LtFromEntriess1, s2s1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), value1 < value2Lt(ak1, ak2)
7TransitiveEqualFromStatementss1, s2s1 = Equal(ak1, ak2), s2 = Equal(ak3, ak4), ak2 = ak3Equal(ak1, ak4)
8LtToNotEqualss = Lt(ak1, ak2)NotEqual(ak1, ak2)
9ContainsFromEntriess1, s2, s3, proofs1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), s3 = ValueOf(ak3, value3), merkle_includes(value1, value2, value3, proof) = trueContains(ak1, ak2, ak3)
10NotContainsFromEntriess1, s2, proofs1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), merkle_excludes(value1, value2, proof) = trueNotContains(ak1, ak2)
11SumOfs1, s2, s3s1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), s3 = ValueOf(ak3, value3), value1 = value2 + value3SumOf(ak1, ak2, ak3)
12ProductOfs1, s2, s3s1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), s3 = ValueOf(ak3, value3), value1 = value2 * value3ProductOf(ak1, ak2, ak3)
13MaxOfs1, s2, s3s1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), s3 = ValueOf(ak3, value3), value1 = max(value2, value3)MaxOf(ak1, ak2, ak3)
14HashOfs1, s2, s3s1 = ValueOf(ak1, value1), s2 = ValueOf(ak2, value2), s3 = ValueOf(ak3, value3), value1 = hash(value2, value3)HashOf(ak1, ak2, ak3)



The following table summarizes "syntactic sugar" operations. These operations are not supported by the backend. The frontend compiler is responsible for translating these operations into the operations above.

CodeIdentifierArgs and desugaring
1001DictContainsFromEntriesDictContainsFromEntries(dict_st, key_st, value_st) -> ContainsFromEntries(dict_st, key_st, value_st)
1002DictNotContainsFromEntriesDictNotContainsFromEntries(dict_st, key_st, value_st) -> NotContainsFromEntries(dict_st, key_st, value_st)
1003SetContainsFromEntriesSetContainsFromEntries(set_st, value_st) -> ContainsFromEntries(set_st, value_st, value_st)
1004SetNotContainsFromEntriesSetNotContainsFromEntries(set_st, value_st) -> NotContainsFromEntries(set_st, value_st, value_st)
1005ArrayContainsFromEntriesArrayContainsFromEntries(array_st, index_st, value_st) -> ContainsFromEntries(array_st, index_st, value_st)
1006GtEqFromEntriesGtEqFromEntries(s1, s2) -> LtEqFromEntries(s2, s1)
1007GtFromEntriesGtFromEntries(s1, s2) -> LtFromEntries(s2, s1)
1008GtToNotEqualGtToNotEqual(s1, s2) -> LtToNotEqual(s1, s2)



WIP. The following table defines more operations that are not yet implemented.
Issue keeping track of the operations: #108.

CodeIdentifierArgsConditionOutput
SymmetricEqss = Equal(ak1, ak2)Eq(ak2, ak1)
SymmetricNEqss = NotEqual(ak1, ak2)NEq(ak2, ak1)
RenameSintainss1, s2s1 = Sintains(ak1, ak2), s2 = Equal(ak3, ak4), ak1 = ak3Sintains(ak4, ak2)
TransitiveEqs1, s2s1 = Equal(ak1, ak2), s2 = Equal(ak3, ak4), ak2 = ak3Eq(ak1, ak4)
TransitiveGts1, s2s1 = Gt(ak1, ak2), s2 = Gt(ak3, ak4), ak2 = ak3Gt(ak1, ak4)
TransitiveLEqs1, s2s1 = LEq(ak1, ak2), s2 = LEq(ak3, ak4), ak2 = ak3LEq(ak1, ak4)
LEqToNEqss = LEq(ak1, ak2)NEq(ak1, ak2)
1

Since new key-value pairs are not constrained, this operation will have no arguments in-circuit.