Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
81
Task/Amb/E/amb-1.e
Normal file
81
Task/Amb/E/amb-1.e
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
pragma.enable("accumulator")
|
||||
|
||||
def [amb, unamb] := { # block hides internals
|
||||
|
||||
def Choice := Tuple[any, Map]
|
||||
|
||||
def [ambS, ambU] := <elib:sealing.makeBrand>("amb")
|
||||
var counter := 0 # Used just for printing ambs
|
||||
|
||||
/** Check whether two sets of decisions are consistent */
|
||||
def consistent(decA, decB) {
|
||||
def overlap := decA.domain() & decB.domain()
|
||||
for ambObj in overlap {
|
||||
if (decA[ambObj] != decB[ambObj]) { return false }
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/** From an amb object, extract the possible choices */
|
||||
def getChoices(obj, decisions) :List[Choice] {
|
||||
if (decisions.maps(obj)) {
|
||||
return [[decisions[obj], decisions]]
|
||||
} else if (ambU.amplify(obj) =~ [[choices, _]]) {
|
||||
return accum [] for [chosen, dec] ? (consistent(decisions, dec)) in choices { _ + getChoices(chosen, (decisions | dec).with(obj, chosen)) }
|
||||
} else {
|
||||
return [[obj, decisions]]
|
||||
}
|
||||
}
|
||||
|
||||
/** Construct an amb object with remembered decisions */
|
||||
def ambDec(choices :List[Choice]) {
|
||||
def serial := (counter += 1)
|
||||
def ambObj {
|
||||
to __printOn(out) {
|
||||
out.print("<amb(", serial, ")")
|
||||
for [chosen, decisions] in choices {
|
||||
out.print(" ", chosen)
|
||||
for k => v in decisions {
|
||||
out.print(";", ambU.amplify(k)[0][1], "=", v)
|
||||
}
|
||||
}
|
||||
out.print(">")
|
||||
}
|
||||
to __optSealedDispatch(brand) {
|
||||
if (brand == ambS.getBrand()) {
|
||||
return ambS.seal([choices, serial])
|
||||
}
|
||||
}
|
||||
match [verb, args] {
|
||||
var results := []
|
||||
for [rec, rdec] in getChoices(ambObj, [].asMap()) {
|
||||
def expandArgs(dec, prefix, choosing) {
|
||||
switch (choosing) {
|
||||
match [] { results with= [E.call(rec, verb, prefix), dec] }
|
||||
match [argAmb] + moreArgs {
|
||||
for [arg, adec] in getChoices(argAmb, dec) {
|
||||
expandArgs(adec, prefix.with(arg), moreArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
expandArgs(rdec, [], args)
|
||||
}
|
||||
ambDec(results)
|
||||
}
|
||||
}
|
||||
return ambObj
|
||||
}
|
||||
|
||||
/** Construct an amb object with no remembered decisions. (public interface) */
|
||||
def amb(choices) {
|
||||
return ambDec(accum [] for c in choices { _.with([c, [].asMap()]) })
|
||||
}
|
||||
|
||||
/** Get the possible results from an amb object, discarding decision info. (public interface) */
|
||||
def unamb(ambObj) {
|
||||
return accum [] for [c,_] in getChoices(ambObj, [].asMap()) { _.with(c) }
|
||||
}
|
||||
|
||||
[amb, unamb]
|
||||
}
|
||||
18
Task/Amb/E/amb-2.e
Normal file
18
Task/Amb/E/amb-2.e
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
def join(a, b) {
|
||||
# This must not use the builtin if, since it coerces to boolean rather than passing messages.
|
||||
# false.pick(x, y) returns y and true.pick(x, y) returns x; we protect the amb([]) from causing
|
||||
# unconditional failure by putting both options in functions.
|
||||
# <=> is the comparison operator that happens to be message-based.
|
||||
return (a.last() <=> b[0]).pick(fn {
|
||||
a + " " + b
|
||||
}, fn {
|
||||
amb([])
|
||||
})()
|
||||
}
|
||||
|
||||
def w1 := amb(["the", "that", "a" ])
|
||||
def w2 := amb(["frog", "elephant", "thing" ])
|
||||
def w3 := amb(["walked", "treaded", "grows" ])
|
||||
def w4 := amb(["slowly", "quickly" ])
|
||||
|
||||
unamb(join(join(join(w1, w2), w3), w4))
|
||||
Loading…
Add table
Add a link
Reference in a new issue