Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute hashes correctly when constructing internalised collections #568

Merged
merged 13 commits into from
Apr 4, 2024

Conversation

geo2a
Copy link
Contributor

@geo2a geo2a commented Apr 3, 2024

This PR fixes a bug in the computation of the synthesis bottom-up hash attribute of Terms representing internalised maps and sets.
These hashes are used in the Eq instance for Term to quilcky check if two terms are equal, akin to a Merkle tree.

Summary of changes:

  • the commits 348f852, 17005f2 and df6a063 comprise the main fix, i.e. correct how the KMap and KSet pattern-synonyms compute the hashes;
  • b7aac44 makes sure we foldl' rather than foldr in some of the cases, as we should use the left fold for data as rule of thumb for better performance. I did not check the impact of this commit specifically though;
  • there are some more stylistic changes and unit tests for the first change.

@ehildenb
Copy link
Member

ehildenb commented Apr 3, 2024

We must have a testing harness for this, and multiple tests! Ideally unit and integration!

@geo2a geo2a force-pushed the georgy/fix-collection-hashes branch from 3dcf217 to 3d58ba3 Compare April 3, 2024 15:09
@geo2a
Copy link
Contributor Author

geo2a commented Apr 3, 2024

Yeah, I'm adding unit tests now.

@geo2a
Copy link
Contributor Author

geo2a commented Apr 3, 2024

KEVM performance at commit b7aac44 with 3 workers. The numbers may be skewed and the code is still wrong anyway. I'm rerunning with 3d58ba3 and 1 worker.

Test georgy-fix-collection-hashes time master-bafee82 time (georgy-fix-collection-hashes/master-bafee82) time
kontrol/test-emitcontracttest-testexpectemit-0-spec.k 53.79 116.85 0.4603337612323492
kontrol/test-storetest-testaccesses-0-spec.k 54.16 115.96 0.467057606071059
kontrol/test-emitcontracttest-testexpectemitcheckemitter-0-spec.k 52.53 71.11 0.7387146674166785
mcd/flipper-ttl-pass-spec.k 59.66 78.15 0.7634037108125399
kontrol/test-allowchangestest-testallow_fail-0-spec.k 55.79 66.72 0.8361810551558753
kontrol/test-expectreverttest-testfail_expectrevert_false-0-spec.k 81.23 96.83 0.8388929050913974
erc20/hkg/transferFrom-success-1-spec.k 66.82 77.02 0.867566865749156
mcd/vat-slip-pass-rough-spec.k 121.16 126.05 0.9612058706862356
kontrol/test-arithmetictest-test_max1_broken-uint256-uint256-0-spec.k 51.62 49.78 1.036962635596625
mcd/vat-addui-fail-rough-spec.k 85.58 81.8 1.0462102689486552
erc20/ds/transferFrom-failure-1-a-spec.k 93.67 89.46 1.0470601386094345
mcd/vat-subui-fail-rough-spec.k 95.21 89.88 1.059301290609702
erc20/hkg/transferFrom-success-2-spec.k 77.34 66.35 1.165636774679729
kontrol/test-allowchangestest-testfailallowcallstoaddress-0-spec.k 70.87 57.4 1.2346689895470384
kontrol/test-expectcalltest-testexpectstaticcall-0-spec.k 71.36 52.58 1.3571700266260935
kontrol/test-expectcalltest-testexpectregularcall-0-spec.k 117.04 51.96 2.252501924557352
TOTAL 1207.83 1287.9 0.9378290239925459

@geo2a geo2a marked this pull request as ready for review April 3, 2024 18:51
(keyVals', rest') = case rest of
Just (KMap def' kvs r) | def' == def -> (kvs, r)
Just (KMap def' kvs r) | def' == def -> (sortAndDeduplicate kvs, r)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) probably not necessary to deduplicate here, as this list comes from a KMap (with this change, we add an invariant that the list should always be sorted and without duplicates)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. I've added this only because of this unit test that manually constructs a nested KMap with a broken invariant. This should never happen thought, so probably safe to remove the call to sortAndDeduplicate form here and also from the same case in KSet.

Gen.int (Range.linear 0 1024)
let setTerm = makeKSetNoRest xs
res <- LLVM.simplifyTerm api testDef setTerm (SortApp "SortSet" [])
res === Right (setAsConcat . map wrapIntTerm $ xs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way this is failing in CI indicates that the smart constructor for SymbolApplication is not generating the expected KSet (both res and the setAsConcat result are not KSets).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the thorough investigation @jberthold. I have to admit I though the test would ensure that the LLVM backend does not change the ordering of concrete sets (or would detect if it did), but upon introducing the changes, we are already comparing two internalised sets, which now de-duplicate and sort themselves, so I'm not sure if this test is helpful in the end.

, concatSymbolName = "Lbl'Unds'Set'Unds'"
}
, elementSortName = "SortKItem"
, listSortName = "SortList"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
, listSortName = "SortList"
, listSortName = "SortSet"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it turns out, there is more to fix... the definition in the LLVM.hs file does not have the collection metadata on SortSet and the (SetItem, _Set_, .Set).
The whole definition is outdated and we should update it (see displayTestDef).
After adding the metadata locally, I found that setAsConcat is not generating the right thing...

Comment on lines 238 to 244
foldl1'
( \x y ->
SymbolApplication
(defSymbols Map.! sortSetKSet.symbolNames.concatSymbolName)
[]
[singletonSet x, singletonSet y]
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I found after fixing the metadata for SortSet, this will produce nested sets when applied to a list with more than two elements: [1, 2, 3] maps to { 3, {2, 1}} (paraphrased) (thanks to the generous KItem sorting, this is even -almost- allowed, but the construction does not have the required injections).

Suggested change
foldl1'
( \x y ->
SymbolApplication
(defSymbols Map.! sortSetKSet.symbolNames.concatSymbolName)
[]
[singletonSet x, singletonSet y]
)
foldl1'
( \x y ->
SymbolApplication
(defSymbols Map.! sortSetKSet.symbolNames.concatSymbolName)
[]
[x, y]
) . map singletonSet

@geo2a
Copy link
Contributor Author

geo2a commented Apr 4, 2024

KEVM performance at commit 3d58ba3 with 1 worker

Test georgy-fix-collection-hashes time master-bafee82 time (georgy-fix-collection-hashes/master-bafee82) time
mcd/flopper-file-pass-rough-spec.k 439.37 463.1 0.9487583675232131
erc20/hkg/transferFrom-success-1-spec.k 64.09 66.82 0.9591439688715955
erc20/ds/transferFrom-failure-2-c-spec.k 57.93 55.79 1.038358128696899
erc20/ds/transferFrom-success-1-spec.k 98.77 94.32 1.0471798134011874
TOTAL 660.16 680.03 0.970780700851433

@geo2a geo2a force-pushed the georgy/fix-collection-hashes branch from 500715b to 9f5ed34 Compare April 4, 2024 09:08
Copy link
Member

@jberthold jberthold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👍

@geo2a geo2a added the automerge label Apr 4, 2024
@rv-jenkins rv-jenkins merged commit 34305b1 into main Apr 4, 2024
5 checks passed
@rv-jenkins rv-jenkins deleted the georgy/fix-collection-hashes branch April 4, 2024 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants