Files
mercury/tests/hard_coded/psqueue_test.exp
Zoltan Somogyi 6b9afbdd9f Significantly improve psqueue.m.
library/psqueue.m:
    Fix a bug: the adjust predicate was documented to fail if asked to adjust
    the priority of a nonexistent key, but it succeeded anyway.

    Fix a bug: the function that computed the size of a psqueue did not count
    the priority/key pair in the winner structure.

    Make the at_most predicate significantly more efficient, by eliminating
    an expensive conversion to the min view. Most of the contents of the min
    view was not needed. In Haskell (the language used in the paper that
    this module is derived from), computing stuff that won't be looked at
    is cheap due to lazyness; in Mercury, it can be expensive.

    Make the at_most predicate significantly more efficient in another respect
    as well, by using cords to avoid re-re-re-appending the same elements.

    Make most other predicates more efficient by eliminating the redundant
    checking for empty queues. For example, when you convert a nonempty queue
    to the tournament view, you shouldn't need to check whether the result
    is a tournament with no players; it will not be. This change required
    two main changes in data structures. The first is to separate out
    the concepts of psqueues that may be empty from those which may not.
    The second is updating the tournament view to eliminate the possibility
    of no players, and handling empty psqueues *without* converting them
    to the tournament view.

    Document the meanings of the module's data structures, both original
    and updated, including their invariants (at least, the invariants
    I can see).

    Delete the type for min views, since after the performance fix to at_most,
    it is no longer needed.

    Delete the type for tree views, since it is isomorphic to the actual
    data structure, and conversions to it just waste time.

    Delete the t_ prefix from the names of types.

    Change the documentation of predicates to use full sentences, not just
    sentence fragments.

    Do not include the predicates intended only for unit tests in the
    publicly documented part of the interface.

    Use the P, K order of type variables CONSISTENTLY. Change the order
    of fields representing priority/key pairs in structures likewise.

    Use consistent naming schemes for variables: PSQx for psqueues, LTreex
    for ltrees, etc. Use xPrime instead of x0 for variables bound in the
    conditions of if-then-elses. Use Maybe as a prefix on the names of
    variables of maybe types.

    Avoid the use of generic variable names such as "Res"; use names that
    reflect the value being returned instead.

    Avoid the use of numeric suffixes on variables when these do NOT denote
    progression over time; use A and B, or L and R, suffixes instead.

    Give some function symbols and predicates more meaningful names.

    Internal operations do not need to be available as both functions
    and predicates; pick whichever seems more appropriate, and remove
    the other. Remove some other unused functions, such as construct_leaf.

    Factor out some common code, e.g. for updating minimums and maximums.

    Remove redundant "is det" declarations from functions.

    Fix the type specializations. Specializing a predicate is useless
    unless its caller either always calls it with values of the specialized
    type, or is itself specialized the same way. This module needs the latter,
    so add type specializations to all predicates between the exported
    predicates and the primitives that can directly benefit from the
    specializations.

tests/hard_coded/psqueue_test.{m,exp}:
    Make this test case significantly harder. The old version did not
    pick up the two bugs referred to above, but the new version does.
2014-12-12 17:42:39 +11:00

323 lines
9.4 KiB
Plaintext

empty test: ok
nonempty test: ok
empty test after remove: ok
extended paper example test:
size before insert is 0
inserting prio 1, key Lennart2, giving
winner(prio 1, key "Lennart2", maxkey "Lennart2",
loser_leaf
)
size after insert is 1
size before insert is 1
inserting prio 8, key Warren, giving
winner(prio 1, key "Lennart2", maxkey "Warren",
loser_node(size 1, prio 8, key "Warren"
loser_leaf
split key "Lennart2"
loser_leaf
)
)
size after insert is 2
size before insert is 2
inserting prio 2, key Erik, giving
winner(prio 1, key "Lennart2", maxkey "Warren",
loser_node(size 2, prio 8, key "Warren"
loser_node(size 1, prio 2, key "Erik"
loser_leaf
split key "Erik"
loser_leaf
)
split key "Lennart2"
loser_leaf
)
)
size after insert is 3
size before insert is 3
inserting prio 7, key Richard, giving
winner(prio 1, key "Lennart2", maxkey "Warren",
loser_node(size 3, prio 7, key "Richard"
loser_node(size 1, prio 2, key "Erik"
loser_leaf
split key "Erik"
loser_leaf
)
split key "Lennart2"
loser_node(size 1, prio 8, key "Warren"
loser_leaf
split key "Richard"
loser_leaf
)
)
)
size after insert is 4
size before insert is 4
inserting prio 5, key Simon, giving
winner(prio 1, key "Lennart2", maxkey "Warren",
loser_node(size 4, prio 5, key "Simon"
loser_node(size 1, prio 2, key "Erik"
loser_leaf
split key "Erik"
loser_leaf
)
split key "Lennart2"
loser_node(size 2, prio 7, key "Richard"
loser_leaf
split key "Richard"
loser_node(size 1, prio 8, key "Warren"
loser_leaf
split key "Simon"
loser_leaf
)
)
)
)
size after insert is 5
size before insert is 5
inserting prio 4, key Charles, giving
winner(prio 1, key "Lennart2", maxkey "Warren",
loser_node(size 5, prio 5, key "Simon"
loser_node(size 2, prio 2, key "Erik"
loser_node(size 1, prio 4, key "Charles"
loser_leaf
split key "Charles"
loser_leaf
)
split key "Erik"
loser_leaf
)
split key "Lennart2"
loser_node(size 2, prio 7, key "Richard"
loser_leaf
split key "Richard"
loser_node(size 1, prio 8, key "Warren"
loser_leaf
split key "Simon"
loser_leaf
)
)
)
)
size after insert is 6
size before insert is 6
inserting prio 6, key Mary, giving
winner(prio 1, key "Lennart2", maxkey "Warren",
loser_node(size 6, prio 5, key "Simon"
loser_node(size 2, prio 2, key "Erik"
loser_node(size 1, prio 4, key "Charles"
loser_leaf
split key "Charles"
loser_leaf
)
split key "Erik"
loser_leaf
)
split key "Lennart2"
loser_node(size 3, prio 6, key "Mary"
loser_node(size 1, prio 7, key "Richard"
loser_leaf
split key "Mary"
loser_leaf
)
split key "Richard"
loser_node(size 1, prio 8, key "Warren"
loser_leaf
split key "Simon"
loser_leaf
)
)
)
)
size after insert is 7
size before insert is 7
inserting prio 3, key Phil, giving
winner(prio 1, key "Lennart2", maxkey "Warren",
loser_node(size 7, prio 3, key "Phil"
loser_node(size 2, prio 2, key "Erik"
loser_node(size 1, prio 4, key "Charles"
loser_leaf
split key "Charles"
loser_leaf
)
split key "Erik"
loser_leaf
)
split key "Lennart2"
loser_node(size 4, prio 5, key "Simon"
loser_node(size 2, prio 6, key "Mary"
loser_leaf
split key "Mary"
loser_node(size 1, prio 7, key "Richard"
loser_leaf
split key "Phil"
loser_leaf
)
)
split key "Richard"
loser_node(size 1, prio 8, key "Warren"
loser_leaf
split key "Simon"
loser_leaf
)
)
)
)
size after insert is 8
size before insert is 8
inserting prio 1, key Lennart, giving
winner(prio 1, key "Lennart", maxkey "Warren",
loser_node(size 8, prio 3, key "Phil"
loser_node(size 3, prio 2, key "Erik"
loser_node(size 1, prio 4, key "Charles"
loser_leaf
split key "Charles"
loser_leaf
)
split key "Erik"
loser_node(size 1, prio 1, key "Lennart2"
loser_leaf
split key "Lennart"
loser_leaf
)
)
split key "Lennart2"
loser_node(size 4, prio 5, key "Simon"
loser_node(size 2, prio 6, key "Mary"
loser_leaf
split key "Mary"
loser_node(size 1, prio 7, key "Richard"
loser_leaf
split key "Phil"
loser_leaf
)
)
split key "Richard"
loser_node(size 1, prio 8, key "Warren"
loser_leaf
split key "Simon"
loser_leaf
)
)
)
)
size after insert is 9
size before insert is 9
inserting prio 2, key Erik2, giving
winner(prio 1, key "Lennart", maxkey "Warren",
loser_node(size 9, prio 3, key "Phil"
loser_node(size 4, prio 2, key "Erik"
loser_node(size 1, prio 4, key "Charles"
loser_leaf
split key "Charles"
loser_leaf
)
split key "Erik"
loser_node(size 2, prio 1, key "Lennart2"
loser_node(size 1, prio 2, key "Erik2"
loser_leaf
split key "Erik2"
loser_leaf
)
split key "Lennart"
loser_leaf
)
)
split key "Lennart2"
loser_node(size 4, prio 5, key "Simon"
loser_node(size 2, prio 6, key "Mary"
loser_leaf
split key "Mary"
loser_node(size 1, prio 7, key "Richard"
loser_leaf
split key "Phil"
loser_leaf
)
)
split key "Richard"
loser_node(size 1, prio 8, key "Warren"
loser_leaf
split key "Simon"
loser_leaf
)
)
)
)
size after insert is 10
at_most tests
at_most 0: []
at_most 1: [1 - "Lennart", 1 - "Lennart2"]
at_most 2: [2 - "Erik", 2 - "Erik2", 1 - "Lennart", 1 - "Lennart2"]
at_most 3: [2 - "Erik", 2 - "Erik2", 1 - "Lennart", 1 - "Lennart2", 3 - "Phil"]
at_most 4: [4 - "Charles", 2 - "Erik", 2 - "Erik2", 1 - "Lennart", 1 - "Lennart2", 3 - "Phil"]
at_most 5: [4 - "Charles", 2 - "Erik", 2 - "Erik2", 1 - "Lennart", 1 - "Lennart2", 3 - "Phil", 5 - "Simon"]
at_most 6: [4 - "Charles", 2 - "Erik", 2 - "Erik2", 1 - "Lennart", 1 - "Lennart2", 6 - "Mary", 3 - "Phil", 5 - "Simon"]
at_most 7: [4 - "Charles", 2 - "Erik", 2 - "Erik2", 1 - "Lennart", 1 - "Lennart2", 6 - "Mary", 3 - "Phil", 7 - "Richard", 5 - "Simon"]
at_most 8: [4 - "Charles", 2 - "Erik", 2 - "Erik2", 1 - "Lennart", 1 - "Lennart2", 6 - "Mary", 3 - "Phil", 7 - "Richard", 5 - "Simon", 8 - "Warren"]
at_most 9: [4 - "Charles", 2 - "Erik", 2 - "Erik2", 1 - "Lennart", 1 - "Lennart2", 6 - "Mary", 3 - "Phil", 7 - "Richard", 5 - "Simon", 8 - "Warren"]
to_ord_assoc_list test:
[1 - "Lennart", 1 - "Lennart2", 2 - "Erik", 2 - "Erik2", 3 - "Phil", 4 - "Charles", 5 - "Simon", 6 - "Mary", 7 - "Richard", 8 - "Warren"]
delete tests
delete key Lennart2: prio 1, left [1 - "Lennart", 2 - "Erik", 2 - "Erik2", 3 - "Phil", 4 - "Charles", 5 - "Simon", 6 - "Mary", 7 - "Richard", 8 - "Warren"]
delete key Warren: prio 8, left [1 - "Lennart", 1 - "Lennart2", 2 - "Erik", 2 - "Erik2", 3 - "Phil", 4 - "Charles", 5 - "Simon", 6 - "Mary", 7 - "Richard"]
delete key Erik: prio 2, left [1 - "Lennart", 1 - "Lennart2", 2 - "Erik2", 3 - "Phil", 4 - "Charles", 5 - "Simon", 6 - "Mary", 7 - "Richard", 8 - "Warren"]
delete key Richard: prio 7, left [1 - "Lennart", 1 - "Lennart2", 2 - "Erik", 2 - "Erik2", 3 - "Phil", 4 - "Charles", 5 - "Simon", 6 - "Mary", 8 - "Warren"]
delete key Simon: prio 5, left [1 - "Lennart", 1 - "Lennart2", 2 - "Erik", 2 - "Erik2", 3 - "Phil", 4 - "Charles", 6 - "Mary", 7 - "Richard", 8 - "Warren"]
delete key Charles: prio 4, left [1 - "Lennart", 1 - "Lennart2", 2 - "Erik", 2 - "Erik2", 3 - "Phil", 5 - "Simon", 6 - "Mary", 7 - "Richard", 8 - "Warren"]
delete key Mary: prio 6, left [1 - "Lennart", 1 - "Lennart2", 2 - "Erik", 2 - "Erik2", 3 - "Phil", 4 - "Charles", 5 - "Simon", 7 - "Richard", 8 - "Warren"]
delete key Phil: prio 3, left [1 - "Lennart", 1 - "Lennart2", 2 - "Erik", 2 - "Erik2", 4 - "Charles", 5 - "Simon", 6 - "Mary", 7 - "Richard", 8 - "Warren"]
delete key Lennart: prio 1, left [1 - "Lennart2", 2 - "Erik", 2 - "Erik2", 3 - "Phil", 4 - "Charles", 5 - "Simon", 6 - "Mary", 7 - "Richard", 8 - "Warren"]
delete key Erik2: prio 2, left [1 - "Lennart", 1 - "Lennart2", 2 - "Erik", 3 - "Phil", 4 - "Charles", 5 - "Simon", 6 - "Mary", 7 - "Richard", 8 - "Warren"]
delete key NotThere: failed
from_assoc_list test:
via from_assoc_list and via inserts assoc lists agree:
[0 - "M", 1 - "L", 2 - "B", 3 - "N", 4 - "H"]
via from_assoc_list and via inserts psqueues agree:
winner(prio 0, key "M", maxkey "N",
loser_node(size 4, prio 2, key "B"
loser_node(size 1, prio 4, key "H"
loser_leaf
split key "B"
loser_leaf
)
split key "H"
loser_node(size 2, prio 1, key "L"
loser_leaf
split key "L"
loser_node(size 1, prio 3, key "N"
loser_leaf
split key "M"
loser_leaf
)
)
)
)
adjust tests on
[0 - "M", 1 - "L", 2 - "B", 3 - "N", 4 - "H"]
adjusting priority of H to 0 succeeded
[0 - "H", 0 - "M", 1 - "L", 2 - "B", 3 - "N"]
adjusting priority of L to 8 succeeded
[0 - "M", 2 - "B", 3 - "N", 4 - "H", 8 - "L"]
adjusting priority of B to 2 succeeded
[0 - "M", 1 - "L", 2 - "B", 3 - "N", 4 - "H"]
adjusting priority of M to 2 succeeded
[1 - "L", 2 - "B", 2 - "M", 3 - "N", 4 - "H"]
adjusting priority of N to 1 succeeded
[0 - "M", 1 - "L", 1 - "N", 2 - "B", 4 - "H"]
adjusting priority of X to 7 failed