# Copyright 2005-2007 Kevin Reid, under the terms of the MIT X license # found at http://www.opensource.org/licenses/mit-license.html ................ ? def makeCoercedSlot := ; null XXX we should define our semitransparent type here, not rely on CoercedSlot being this incidentally Premises ? def a {} # value: ? def b {} # value: ? __equalizer # value: ? def semiA1 := makeCoercedSlot(any, 1, null) > def semiA2 := makeCoercedSlot(any, 1, null) > def semiB := makeCoercedSlot(any, 2, null) > def semiU := makeCoercedSlot(any, Ref.promise()[0], null) >null Algorithm checking ? __equalizer.optSame(a, b) # value: false ? __equalizer.optSame(a, a) # value: true ? [1, 1000000000000000000001 - 1000000000000000000000] # value: [1, 1] ? __equalizer.optSame(1, 1.0) # value: false ? __equalizer.optSame(1, 1000000000000000000001 - 1000000000000000000000) # value: true ? __equalizer.optSame([1], [1]) # value: true ? __equalizer.optSame([1], [2]) # value: false ? def unresolved := Ref.promise()[0] # value: ? [__equalizer.optSame(1, unresolved)] # value: [null] ? [__equalizer.optSame(unresolved, unresolved)] # value: [true] ? [__equalizer.optSame([unresolved], [unresolved])] # value: [true] ? [__equalizer.optSame(unresolved, Ref.promise()[0])] # value: [null] ? [__equalizer.optSame(def circle := [circle], def loop := [loop])] # value: [true] ? [__equalizer.optSame(def circle := [1, [1, circle]], def loop := [1, loop])] # value: [true] ? [__equalizer.optSame('q', 'q')] # value: [true] ? [__equalizer.optSame('q', 'w')] # value: [false] ? "a" + "bc" # value: "abc" ? [__equalizer.optSame("abc", "a" + "bc")] # value: [true] ? [__equalizer.optSame(['a', 'b', 'c'], "a" + "bc")] # value: [false] ? [__equalizer.optSame(semiA1, semiA2)] # value: [true] ? [__equalizer.optSame(semiA1, semiB)] # value: [false] ? [__equalizer.optSame(semiA1, semiU)] # value: [null] Former bug: the sofar list was sometimes being filled with the right-side reference only (broken swap), so a cycle on the right would be assumed to be a cycle on the left as well. The test is done with two sets of references because whether the swap occurs depends on the hash-values involved. ? def l1 := [[[l1]]] > def c1 := [[[[[['a']]]]]] > def l2 := [[[l2]]] > def c2 := [[[[[['b']]]]]] > [c1 == l1, c1 == l2, c2 == l1, c2 == l2, > l1 == c1, l1 == c2, l2 == c1, l2 == c2] # value: [false, false, false, false, false, false, false, false] isSettled ? __equalizer.isSettled(semiA1) # value: true ? __equalizer.isSettled(semiU) # value: false XXX move other isSettled tests to this file User-level conveniences etc. We assume that they derive from optSame properly. sameEver ? 1 == 1 # value: true ? 1 == 2 # value: false ? 1 == unresolved # problem: > ? a == unresolved # problem: == > sameYet ? __equalizer.sameYet(1, 1) # value: true ? __equalizer.sameYet(1, 2) # value: false ? __equalizer.sameYet(1, unresolved) # value: false TraversalKey ? pragma.enable("verb-curry") > def makeTraversalKey := __equalizer.makeTraversalKey; null ? def k83 := makeTraversalKey(83) # value: ? def k84 := makeTraversalKey(84) # value: ? k84 == k84 # value: true ? k84 == k83 # value: false ? k83 == 83 # value: false ? k83 == makeTraversalKey(83) # value: true ? makeTraversalKey(unresolved) == k84 # value: false ? makeTraversalKey(unresolved) == makeTraversalKey(unresolved) # value: true ? makeTraversalKey([unresolved, 5]) == makeTraversalKey([unresolved, 5]) # value: true ? makeTraversalKey([unresolved, 5]) == makeTraversalKey([unresolved, 6]) # value: false Checking that TKs respect differing fringe positions. There was a bug where TK sameness just checked that the objects had the same hash, same *set* of then-promise-identities and were currently same-yet. That strategy breaks in this case. ? def p # value: ? def [ka1, kb1] := [makeTraversalKey([1, p]), makeTraversalKey([p, 1])] # value: [, ] ? def [ka2, kb2] := [makeTraversalKey([p, p, 1]), makeTraversalKey([p, 1, p])] # value: [, ] ? def [ka3, kb3] := [makeTraversalKey([p, 1, p]), makeTraversalKey([1, p, p])] # value: [, ] ? [ka1 == kb1, ka2 == kb2, ka3 == kb3] # value: [false, false, false] ? bind p := 1 # value: 1 ? [ka1 == kb1, ka2 == kb2, ka3 == kb3] # value: [false, false, false] (The bug caused these to be true.) PassByCopy ? a :PassByCopy # problem: not PassByCopy: ? 1 :PassByCopy # problem: not PassByCopy: 1 ? [1,2,3] :PassByCopy # value: [1, 2, 3] ? [1,2,any] :PassByCopy # value: [1, 2, any] ? any :PassByCopy # problem: not PassByCopy: any Making sure that the sameness algorithm doesn't fail for lack of settledness if it doesn't need to: Premises ? def al := [1, 2, 3] # value: [1, 2, 3] ? def p # value: Different length of uncall list is sufficient ? al == [1, 2, 3, p] # value: false -- from beginning or end ? al == [p, 2, 3, 4] # value: false Promise doesn't require failure, if other elements are different ' ? al == [p, 2, 4] # value: false -- but if they're the same, do fail ' ? al == [p, 2, 3] # problem: , 2, 3]> sameness of UnconnectedRefs xxx expect this to change later ? def Exception := # value: Throwable ? def p := "blip" :Exception # value: problem: blip ? Ref.broken(p) == Ref.broken(p) # value: false should this be true? x ? p == "blip" :Exception x # value: true Bug: CL undefined closure equality was leaking into E when the objects were sufficiently trivial ? { def x() :any { return def y {} } > x() == x() } # value: false Selfless ? Selfless.passes(1) # value: true ? Selfless.passes([]) # value: true ? Selfless.passes([].asMap()) # value: true ? Selfless.passes(def x {}) # value: false ? Selfless.passes([].diverge()) # value: false ? Selfless.passes((def _ {}, Ref.promise()[0], true)) # value: true XXX this is a correct answer, but an incorrect situation ? Selfless.passes((def _ {}, Ref.promise()[0], false)) # value: false Properties of bogus Selfless objects ? def makeBogus() { return def bogus implements Selfless {} } > def bogus := makeBogus() # value: ? __equalizer.optSame(bogus, bogus) # value: true ? [__equalizer.optSame(bogus, makeBogus())] # value: [null] ? Selfless.passes(bogus) # value: true ? __equalizer.isSettled(bogus) # value: false