Java "fastlib"

         
package doglet;
import nova.*;
import java.math.BigInteger;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* Warranty & Liability
* To the extent permitted by applicable law and unless explicitly
* otherwise agreed upon, XLOG Technologies AG makes no warranties
* regarding the provided information. XLOG Technologies AG assumes
* no liability that any problems might be solved with the information
* provided by XLOG Technologies AG.
*
* Rights & License
* All industrial property rights regarding the information - copyright
* and patent rights in particular - are the sole property of XLOG
* Technologies AG. If the company was not the originator of some
* excerpts, XLOG Technologies AG has at least obtained the right to
* reproduce, change and translate the information.
*
* Reproduction is restricted to the whole unaltered document. Reproduction
* of the information is only allowed for non-commercial uses. Selling,
* giving away or letting of the execution of the library is prohibited.
* The library can be distributed as part of your applications and libraries
* for execution provided this comment remains unchanged.
*
* Restrictions
* Only to be distributed with programs that add significant and primary
* functionality to the library. Not to be distributed with additional
* software intended to replace any components of the library.
*
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies AG.
*/
public final class fastlib {
/******************************************************************/
/* term_singletons/2 */
/******************************************************************/
/**
* term_singletons(T, L):
* The built-in succeeds in L with the singleton variables of T.
*/
private static boolean test_term_singletons(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object res;
try {
res = eval.walk_compute(alpha, fastlib::init_map, fastlib::union_map);
} finally {
eval.walk_uncompute(alpha);
}
Iterator it = ((Map)res).entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
if (((Boolean)entry.getValue()).booleanValue())
it.remove();
}
res = theatre.set_to_list(((Map)res).keySet());
return Machine.exec_unify(args[1], res);
}
private static final Map EMPTY_MAP = new LinkedHashMap();
private static Map init_map(Object first) {
if (Store.is_variable(first)) {
return Collections.singletonMap(first, Boolean.FALSE);
} else {
return EMPTY_MAP;
}
}
private static Map union_map(Object alpha, Object beta) {
Map first = (Map)alpha;
Map second = (Map)beta;
if (first.size() == 0)
return second;
if (second.size() == 0)
return first;
first = new LinkedHashMap(first);
Iterator it = second.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
Object value = first.get(entry.getKey());
if (value != null) {
value = Boolean.TRUE;
} else {
value = entry.getValue();
}
first.put(entry.getKey(), value);
}
return first;
}
/******************************************************************/
/* ground/1 and nonground/2 */
/******************************************************************/
/**
* ground(T): [TC2 8.3.10]
* The built-in succceeds if T is ground.
*/
private static boolean test_ground(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
boolean res = special.walk_vars(alpha, node -> true, Store.VAR_MASK_SEEN);
special.walk_vars(alpha, node -> true, 0);
return !res;
}
/**
* nonground(T, V):
* The built-in succeeds if T is non-ground and V is the first variable.
*/
private static boolean test_nonground(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
nonground2 h = new nonground2();
boolean res = special.walk_vars(alpha, h::run, Store.VAR_MASK_SEEN);
special.walk_vars(alpha, node -> true, 0);
return res && Machine.exec_unify(args[1], h.hit);
}
private static class nonground2 {
private Object hit = null;
public boolean run(Object node) {
hit = node;
return true;
}
}
/******************************************************************/
/* divmod/4 and gcd/3 */
/******************************************************************/
/**
* divmod(X, Y, Z, T):
* If X and Y are both integers then the predicate succeeds in
* Z with the division of X by Y, and in T with the modulo of X by Y.
*/
private static boolean test_divmod(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
special.check_integer(alpha);
Object beta = Machine.exec_build(args[1]);
special.check_integer(beta);
Number resdiv;
Number resmod;
if (alpha instanceof Integer && beta instanceof Integer) {
int u = ((Integer) beta).intValue();
if (u == 0)
throw Machine.make_error(new Store.Compound("evaluation_error",
new Object[]{"zero_divisor"}));
int v = ((Integer) alpha).intValue();
if (v == Integer.MIN_VALUE && u == -1) {
resdiv = eval.NEG_MIN_INTEGER;
resmod = Integer.valueOf(0);
} else {
int[] res2 = intDivMod(v, u);
resdiv = Integer.valueOf(res2[0]);
resmod = Integer.valueOf(res2[1]);
}
} else {
BigInteger p = special.widen_bigint((Number) beta);
if (p.signum() == 0)
throw Machine.make_error(new Store.Compound("evaluation_error",
new Object[]{"zero_divisor"}));
BigInteger[] res2 = bigDivMod(special.widen_bigint((Number) alpha), p);
resdiv = special.norm_bigint(res2[0]);
resmod = special.norm_bigint(res2[1]);
}
if (!Machine.exec_unify(args[2],resdiv))
return false;
return Machine.exec_unify(args[3],resmod);
}
private static int[] intDivMod(int v, int u) {
int[] res = new int[2];
res[0] = v / u;
res[1] = v % u;
if ((v < 0) != (u < 0)) {
if (res[1] != 0) {
res[0]--;
res[1] += u;
}
}
return res;
}
private static BigInteger[] bigDivMod(BigInteger v, BigInteger u) {
BigInteger[] res = v.divideAndRemainder(u);
if ((v.signum() < 0) != (u.signum() < 0)) {
if (res[1].signum() != 0) {
res[0] = res[0].subtract(BigInteger.ONE);
res[1] = res[1].add(u);
}
}
return res;
}
/**
* gcd(X, Y, Z):
* If X and Y are integers then the predicate succeeds in Z
* with the greatest common divisor of X and Y.
*/
private static Number arit_gcd(Object[] args) {
Number alpha = Machine.exec_eval(args[0]);
special.check_integer(alpha);
Number beta = Machine.exec_eval(args[1]);
special.check_integer(beta);
if (alpha instanceof Integer && beta instanceof Integer) {
return Integer.valueOf(intGcd(alpha.intValue(),
beta.intValue()));
} else {
return special.norm_bigint(
special.widen_bigint(alpha).gcd(
special.widen_bigint(beta)));
}
}
private static int intGcd(int a, int b) {
a = Math.abs(a);
b = Math.abs(b);
while (b != 0) {
int h = Math.abs(a % b);
a = b;
b = h;
}
return a;
}
/******************************************************************/
/* Fast Lib Init */
/******************************************************************/
public static void main() {
Store.set("term_singletons", 2, special.make_check(fastlib::test_term_singletons));
Store.set("ground", 1, special.make_check(fastlib::test_ground));
Store.set("nonground", 2, special.make_check(fastlib::test_nonground));
Store.set("divmod", 4, special.make_check(fastlib::test_divmod));
Store.set("gcd", 3, special.make_arithmetic(fastlib::arit_gcd));
}
}

Use Privacy (c) 2005-2026 XLOG Technologies AG