June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -1,41 +1,104 @@
|
|||
// version 1.1.3
|
||||
// version 1.2.41
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
typealias Constraint<T> = (T, T) -> Boolean
|
||||
fun main(args: Array<String>) = amb {
|
||||
val a = amb("the", "that", "a")
|
||||
val b = amb("frog", "elephant", "thing")
|
||||
val c = amb("walked", "treaded", "grows")
|
||||
val d = amb("slowly", "quickly")
|
||||
|
||||
fun <T> amb(lists: List<List<T>>, res: MutableList<T>, cons: Constraint<T>): Boolean {
|
||||
if (lists.isEmpty()) return true
|
||||
if (lists[0].isEmpty()) return false
|
||||
val z = res.size
|
||||
for ((i, el) in lists[0].withIndex()) {
|
||||
if (i == 0) res.add(el) else res[z] = el
|
||||
if (z > 0 && !cons(res[z - 1], res[z])) continue
|
||||
if (amb(lists.drop(1), res, cons)) return true
|
||||
if (a[a.lastIndex] != b[0]) amb()
|
||||
if (b[b.lastIndex] != c[0]) amb()
|
||||
if (c[c.lastIndex] != d[0]) amb()
|
||||
|
||||
println(listOf(a, b, c, d))
|
||||
|
||||
|
||||
val x = amb(1, 2, 3)
|
||||
val y = amb(7, 6, 4, 5)
|
||||
if (x * y != 8) amb()
|
||||
println(listOf(x, y))
|
||||
}
|
||||
|
||||
|
||||
class AmbException(): Exception("Refusing to execute")
|
||||
data class AmbPair<T>(val cont: Continuation<T>, val valuesLeft: MutableList<T>)
|
||||
|
||||
@RestrictsSuspension
|
||||
class AmbEnvironment {
|
||||
val ambList = mutableListOf<AmbPair<*>>()
|
||||
|
||||
suspend fun <T> amb(value: T, vararg rest: T): T = suspendCoroutineOrReturn { cont ->
|
||||
if (rest.size > 0) {
|
||||
ambList.add(AmbPair(clone(cont), mutableListOf(*rest)))
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
res.removeAt(z)
|
||||
return false
|
||||
|
||||
suspend fun amb(): Nothing = suspendCoroutine<Nothing> { }
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val wordLists = listOf(
|
||||
listOf("the", "that", "a"),
|
||||
listOf("frog", "elephant", "thing"),
|
||||
listOf("walked", "treaded", "grows"),
|
||||
listOf("slowly", "quickly")
|
||||
)
|
||||
val res = mutableListOf<String>()
|
||||
val cons: Constraint<String> = { x, y -> x.last() == y.first() }
|
||||
if (amb(wordLists, res, cons))
|
||||
println(res)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <R> amb(block: suspend AmbEnvironment.() -> R): R {
|
||||
var result: R? = null
|
||||
var toThrow: Throwable? = null
|
||||
|
||||
val dist = AmbEnvironment()
|
||||
block.startCoroutine(receiver = dist, completion = object : Continuation<R> {
|
||||
override val context: CoroutineContext get() = EmptyCoroutineContext
|
||||
override fun resume(value: R) { result = value }
|
||||
override fun resumeWithException(exception: Throwable) { toThrow = exception }
|
||||
})
|
||||
|
||||
while (result == null && toThrow == null && !dist.ambList.isEmpty()) {
|
||||
val last = dist.ambList.run { this[lastIndex] }
|
||||
|
||||
if (last.valuesLeft.size == 1) {
|
||||
dist.ambList.removeAt(dist.ambList.lastIndex)
|
||||
last.apply {
|
||||
(cont as Continuation<Any?>).resume(valuesLeft[0])
|
||||
}
|
||||
} else {
|
||||
val value = last.valuesLeft.removeAt(last.valuesLeft.lastIndex)
|
||||
(clone(last.cont) as Continuation<Any?>).resume(value)
|
||||
}
|
||||
}
|
||||
|
||||
if (toThrow != null)
|
||||
{
|
||||
throw toThrow!!
|
||||
}
|
||||
else if (result != null)
|
||||
{
|
||||
return result!!
|
||||
}
|
||||
else
|
||||
println("No solution found")
|
||||
val numLists = listOf(
|
||||
listOf(1, 2, 3),
|
||||
listOf(7, 6, 4, 5)
|
||||
)
|
||||
val res2 = mutableListOf<Int>()
|
||||
val cons2: Constraint<Int> = { x, y -> x * y == 8 }
|
||||
if (amb(numLists, res2, cons2))
|
||||
println(res2)
|
||||
else
|
||||
println("No solution found")
|
||||
{
|
||||
throw AmbException()
|
||||
}
|
||||
}
|
||||
|
||||
val UNSAFE = Class.forName("sun.misc.Unsafe")
|
||||
.getDeclaredField("theUnsafe")
|
||||
.apply { isAccessible = true }
|
||||
.get(null) as sun.misc.Unsafe
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T: Any> clone(obj: T): T {
|
||||
val clazz = obj::class.java
|
||||
val copy = UNSAFE.allocateInstance(clazz) as T
|
||||
copyDeclaredFields(obj, copy, clazz)
|
||||
return copy
|
||||
}
|
||||
|
||||
tailrec fun <T> copyDeclaredFields(obj: T, copy: T, clazz: Class<out T>) {
|
||||
for (field in clazz.declaredFields) {
|
||||
field.isAccessible = true
|
||||
val v = field.get(obj)
|
||||
field.set(copy, if (v === obj) copy else v)
|
||||
}
|
||||
val superclass = clazz.superclass
|
||||
if (superclass != null) copyDeclaredFields(obj, copy, superclass)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue