Java "isolib"

         
package doglet;
import nova.Machine;
import nova.Store;
import nova.eval;
import nova.special;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* 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 isolib {
/***************************************************************/
/* @</2, @=</2, @>/2, @>=/2 and compare/3 */
/***************************************************************/
/**
* X @< Y: [ISO 8.4.1]
* The predicate succeeds when X is syntactically less than Y, otherwise fails.
*/
private static boolean test_less(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object beta = Machine.exec_build(args[1]);
return compare_term(alpha, beta) < 0;
}
/**
* X @=< Y: [ISO 8.4.1]
* The predicate succeeds when X is syntactically less or equal to Y, otherwise fails.
*/
private static boolean test_lessequal(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object beta = Machine.exec_build(args[1]);
return compare_term(alpha, beta) <= 0;
}
/**
* X @>= Y: [ISO 8.4.1]
* The predicate succeeds when X is syntactically greater or equal to Y, otherwise fails.
*/
private static boolean test_greaterequal(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object beta = Machine.exec_build(args[1]);
return compare_term(alpha, beta) >= 0;
}
/**
* X @> Y: [ISO 8.4.1]
* The predicate succeeds when X is syntactically greater than Y, otherwise fails.
*/
private static boolean test_greater(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object beta = Machine.exec_build(args[1]);
return compare_term(alpha, beta) > 0;
}
/**
* compare(C, X, Y): [TC2 8.4.2]
* The predicate succeeds when C unifies with the result of comparing
* X to Y. The result is one of the following atoms <, = or >.
*/
private static boolean test_compare(Object[] args) {
Object beta = Machine.exec_build(args[1]);
Object gamma = Machine.exec_build(args[2]);
int k = compare_term(beta, gamma);
if (k < 0) {
beta = "<";
} else if (k == 0) {
beta = "=";
} else {
beta = ">";
}
return Machine.exec_unify(args[0], beta);
}
/**
* Determine the syntactic relationship between two Prolog terms.
* Can handle cyclic terms and deep recursion.
* Has left to right anomaly.
*
* @param first The first Prolog term.
* @param second The second Prolog term.
* @return <0 for less, =0 for equal and >0 for greater
*/
public static int compare_term(Object first, Object second) {
List stack = null;
List log = null;
try {
for (; ; ) {
first = Store.deref(first);
second = Store.deref(second);
if (!Store.is_structure(first)) {
if (!Objects.equals(first, second))
break;
} else if (!Store.is_structure(second)) {
break;
} else if (((Store.Structure) first).args.length !=
((Store.Structure) second).args.length) {
break;
} else {
first = Machine.union_find((Store.Structure) first);
second = Machine.union_find((Store.Structure) second);
if (first != second) {
if (!((Store.Structure) first).functor.equals(
((Store.Structure) second).functor))
break;
log = Machine.union_add(log, (Store.Structure) first,
(Store.Structure) second);
if (0 != ((Store.Structure) first).args.length - 1) {
Store.Item item = new Store.Item((Store.Structure)first, second, 0);
stack = Store.stack_push(stack, item);
}
first = ((Store.Structure) first).args[0];
second = ((Store.Structure) second).args[0];
continue;
}
}
Store.Item item = (Store.Item)Store.stack_peek(stack);
if (item == null) {
return 0;
} else {
item.idx++;
first = item.first.args[item.idx];
second = ((Store.Structure)item.second).args[item.idx];
if (item.idx == item.first.args.length - 1)
Store.stack_pop(stack);
}
}
return compare_truncated(first, second);
} finally {
Machine.union_undo(log);
}
}
/**
* Determine the syntactic relationship between truncated Prolog terms.
* Prolog compounds are truncated to their arity and functor.
*
* @param first The first Prolog term.
* @param second The second Prolog term.
* @return <0 for less, =0 for equal and >0 for greater
*/
private static int compare_truncated(Object first, Object second) {
int i = compare_type(first);
int k = i - compare_type(second);
if (k != 0)
return k;
switch (i) {
case 0:
return Store.variable_serno((Store.Variable)first) -
Store.variable_serno((Store.Variable)second);
case 2:
return ((Double) first).compareTo((Double) second);
case 3:
return eval.integer_compare((Number) first, (Number) second);
case 9:
return ((String) first).compareTo((String) second);
case 10:
k = ((Store.Structure) first).args.length -
((Store.Structure) second).args.length;
if (k != 0)
return k;
return ((String) ((Store.Structure) first).functor).compareTo(
(String) ((Store.Structure) second).functor);
default:
return 0;
}
}
private static int compare_type(Object first) {
if (Store.is_variable(first)) {
return 0;
} else if (Store.is_structure(first)) {
return 10;
} else if (Machine.is_atom(first)) {
return 9;
} else if (Machine.is_number(first)) {
if (Machine.is_integer(first)) {
return 3;
} else if (Machine.is_special(first)) {
if (eval.DOUBLE_NINF.equals(first)) {
return 1;
} else if (eval.DOUBLE_PINF.equals(first)) {
return 4;
} else if (eval.DOUBLE_NAN.equals(first)) {
return 5;
}
} else if (Machine.is_float(first)) {
return 2;
}
} else if (first == Boolean.FALSE) {
return 7;
} else if (first == Boolean.TRUE) {
return 8;
} else if (first == null) {
return 6;
}
throw Machine.make_error(new Store.Compound("resource_error",
new Object[]{"not_supported"}));
}
/******************************************************************/
/* sort/2 and keysort/2 */
/******************************************************************/
/**
* sort(L, R): [TC2 8.4.3]
* The predicate succeeds in R with the sorted list L.
*/
private static boolean test_sort(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object[] res = special.list_objects(alpha);
Arrays.sort(res, isolib::compare_term);
int count = objects_dedup(res);
return Machine.exec_unify(args[1], special.objects_list(res, 0, count));
}
private static int objects_dedup(Object[] res) {
int j = 0;
int i = 0;
while (i < res.length) {
Object alpha = res[i++];
while (i < res.length && eval.equal_term(alpha, res[i]))
i++;
res[j++] = alpha;
}
return j;
}
/**
* keysort(L, R): [TC2 8.4.4]
* The predicate succeeds in R with the key sorted list L.
*/
private static boolean test_keysort(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object[] res = special.list_objects(alpha);
objects_pairs(res);
Arrays.sort(res, (first, second) -> compare_term(get_key(first), get_key(second)));
return Machine.exec_unify(args[1], special.objects_list(res, 0, res.length));
}
private static void objects_pairs(Object[] res) {
for (int i = 0; i < res.length; i++) {
Object alpha = res[i];
if (Store.is_structure(alpha) &&
"-".equals(((Store.Structure) alpha).functor) &&
((Store.Structure) alpha).args.length == 2) {
/* */
} else {
Store.check_nonvar(alpha);
alpha = Store.copy_term(alpha);
throw Machine.make_error(new Store.Compound("type_error",
new Object[]{"pair", alpha}));
}
}
}
private static Object get_key(Object peek) {
return ((Store.Structure) peek).args[0];
}
/******************************************************************/
/* Iso Lib Init */
/******************************************************************/
public static void main() {
// term specials, syntactic comparison
Store.set("@<", 2, special.make_check(isolib::test_less));
Store.set("@=<", 2, special.make_check(isolib::test_lessequal));
Store.set("@>=", 2, special.make_check(isolib::test_greaterequal));
Store.set("@>", 2, special.make_check(isolib::test_greater));
Store.set("compare", 3, special.make_check(isolib::test_compare));
// list specials, miscellaneous sorting
Store.set("sort", 2, special.make_check(isolib::test_sort));
Store.set("keysort", 2, special.make_check(isolib::test_keysort));
}
}

Use Privacy (c) 2005-2026 XLOG Technologies AG