/** AWK~plus: predef for Groovy.
 */
import groovy.transform.*
import plus.concurrent.*
import plus.run.*
# ------------------------------------------------------------------------
# Built-in arithmetic Functions.
# ------------------------------------------------------------------------
# function abs(x: Number): Number { return plus.BiBase.abs(x) }
# function atan2(x: Number, y: Number): Number { return plus.BiBase.atan2(x, y) }
# function cos(x: Number): Number { return plus.BiBase.cos(x) }
# function exp(x: Number): Number { return plus.BiBase.exp(x) }
# function log(x: Number): Number { return plus.BiBase.log(x) }
# function sin(x: Number): Number { return plus.BiBase.sin(x) }
# function sqrt(x: Number): Number { return plus.BiBase.sqrt(x) }
# function rand(): Number { return plus.BiBase.rand() }
# function srand(x: Number*): Number { return plus.BiBase.srand(x) }
function pow(x: Number, y: Number): Number { return Math.pow(x, y) }
function gcd(x: Number, y: Number): Number { # 最大公約数 - greatest common divisor
  var a = x.intValue(); var b = y.intValue()
  while (b != 0) {
    var t = a % b; a = b; b = t
  }
  return a
}
# ------------------------------------------------------------------------
# String Functions.
# ------------------------------------------------------------------------
function index(s: String, t: String): int { return plus.runtime.RunHelper.indexOf(s, t) }
function strtonum(s: String): Number { return plus.util.NumHelper.parseNumber(s) }
function substr(s: String, i: int, n: int): String { return plus.runtime.RunHelper.substr(s, i, n) }
function tolower(s: String): String { return s.toLowerCase() }
function toupper(s: String): String { return s.toUpperCase() }
# ------------------------------------------------------------------------
# I/O Functions.
# ------------------------------------------------------------------------
# function close(x: Object*): Void { return plus.BiIO.close(x) }
# function fflush(x: Object*): Void { return plus.BiIO.fflush(x) }
# function sprintf(x: Object*): String { return plus.BiIO._sprintf(x) }
# function copy(i: String, o: String, x: Object*): int { return BiIO.copy(i, o, x) }
# function move(i: String, o: String, x: Object*): int { return BiIO.move(i, o, x) }
# function remove(s: String, x: Object*): int { return BiIO.remove(s, x) }
# function tree(s: String, x: Object*): int { return BiIO.tree(s, x) }
# function ls(s: String, x: Object*): int { return BiIO.ls(s, x) }
# function set(x: Object*): int { return BiIO.set(x) }
# ------------------------------------------------------------------------
# System Functions.
# ------------------------------------------------------------------------
# Timestamp Functions.
# ------------------------------------------------------------------------
# 日付時刻を表す文字列をタイムスタンプに変換して返す
function mktime(s: String): Double {
    try { return 0.001 * java.text.DateFormat.getDateTimeInstance().parse(s).getTime()
    } catch (java.text.ParseException e) { return -1 }
}
# ------------------------------------------------------------------------
# Concurrent Future Functions.
# ------------------------------------------------------------------------
function Barrier(x: int): Object { return new java.util.concurrent.CyclicBarrier(x) }
function Future(x: Function): Object {
    val e = new java.util.concurrent.FutureTask(x)
    new java.lang.Thread(e).start()
    # Lambda; wait by the analysis completion of the expression
    plus.concurrent.Futures.await(x.toString())
    return e
}
function Cancel(x: Object): Boolean { return plus.concurrent.Futures.cancel(x) }
function Join(x: Object): Boolean { return plus.concurrent.Futures.join(x) }
function isAlive(x: Object): Boolean { return plus.concurrent.Futures.isAlive(x) }
# ------------------------------------------------------------------------
# Concurrent Util Functions.
# ------------------------------------------------------------------------
function Channel(): Object { return new plus.concurrent.SimpleQueue }
function Range(start: int, end: int, step: int*): Object {
    return new plus.concurrent.Range(start, end, 0 in step ? step[0]: 0 > end - start ? -1: 1)
}
function sleep(second: Number): Boolean { return plus.runtime.RunHelper.sleep(second) }
