Java "asmlib"

         
package doglet;
import nova.Machine;
import nova.Store;
import nova.eval;
import nova.special;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 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 asmlib {
/******************************************************************/
/* numbervars/3 */
/******************************************************************/
/**
* numbervars(X, N, M):
* The predicate succeeds in M with the next index after
* numbering all variables in X starting with index N.
*/
private static boolean test_numbervars(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object beta = Machine.exec_build(args[1]);
special.check_integer(beta);
if (eval.integer_signum((Number)beta) >= 0) {
beta = numbervars("$VAR", alpha, (Number) beta);
} else {
beta = eval.subtract(Integer.valueOf(-1), (Number) beta);
beta = numbervars("_", alpha, (Number) beta);
beta = eval.subtract(Integer.valueOf(-1), (Number) beta);
}
return Machine.exec_unify(args[2], beta);
}
private static Number numbervars(String functor, Object alpha, Number beta) {
numbervars2 h = new numbervars2(functor, beta);
special.walk_vars(alpha, node -> false, Store.VAR_MASK_SEEN);
special.walk_vars(alpha, h::run, 0);
return h.beta;
}
private static class numbervars2 {
private final String functor;
private Number beta;
public numbervars2(String functor, Number beta) {
this.functor = functor;
this.beta = beta;
}
public boolean run(Object node) {
Machine.bind(new Store.Compound(functor, new Object[]{beta}),
(Store.Variable)node);
beta = eval.add(beta, Integer.valueOf(1));
return false;
}
}
/**************************************************************/
/* Association Map */
/**************************************************************/
private static Object assoc_get(Map map, Object key) {
if (map == null)
return null;
return map.get(key);
}
private static Map assoc_set(Map map, Object key, Object value) {
if (map == null)
map = new HashMap();
map.put(key, value);
return map;
}
/******************************************************************/
/* unnumbervars/3 */
/******************************************************************/
/**
* unnumbervars(S, N, T):
* The predicate succeeds in T with a copy of S with the
* numbering greater or equal than N replaced by variables.
*/
private static boolean test_unnumbervars(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object beta = Machine.exec_build(args[1]);
special.check_integer(beta);
Object res;
try {
if (eval.integer_signum((Number) beta) >= 0) {
res = walk_replace("$VAR", (Number) beta, alpha);
} else {
res = eval.subtract(Integer.valueOf(-1), (Number) beta);
res = walk_replace("_", (Number) res, alpha);
}
} finally {
if (eval.integer_signum((Number) beta) >= 0) {
walk_unmax("$VAR", alpha);
} else {
walk_unmax("_", alpha);
}
}
return Machine.exec_unify(args[2], res);
}
private static Object walk_replace(String functor, Number beta, Object first) {
List stack = null;
Map map = null;
for (; ; ) {
first = Store.deref(first);
if (Store.is_structure(first)) {
if (functor.equals(((Store.Structure) first).functor) &&
((Store.Structure) first).args.length == 1) {
Object peek = Store.deref(((Store.Structure) first).args[0]);
if (Machine.is_integer(peek) &&
eval.integer_compare(beta, (Number) peek) <= 0) {
first = assoc_get(map, peek);
if (first == null) {
first = new Store.Variable();
map = assoc_set(map, peek, first);
}
}
}
if (Store.is_structure(first)) {
if (!Store.is_compound(((Store.Structure) first).functor)) {
((Store.Structure) first).functor = new Store.Compound(((Store.Structure) first).functor,
new Object[((Store.Structure) first).args.length]);
Store.Item item = new Store.Item((Store.Structure)first, null, 0);
stack = Store.stack_push(stack, item);
first = ((Store.Structure) first).args[0];
continue;
} else {
first = ((Store.Structure) first).functor;
}
}
}
Store.Item item = (Store.Item) Store.stack_peek(stack);
while (item != null &&
item.idx == item.first.args.length - 1) {
((Store.Structure)item.first.functor).args[item.idx] = first;
first = item.first.functor;
Store.stack_pop(stack);
item = (Store.Item) Store.stack_peek(stack);
}
if (item == null) {
return first;
} else {
((Store.Structure)item.first.functor).args[item.idx] = first;
item.idx++;
first = item.first.args[item.idx];
}
}
}
/******************************************************************/
/* maxvars/2 */
/******************************************************************/
/**
* maxvars(X, M):
* The predicate succeeds in M with the max numbering of the term X.
*/
private static boolean test_maxvars(Object[] args) {
Object alpha = Machine.exec_build(args[0]);
Object res;
try {
res = walk_max("$VAR", alpha);
} finally {
walk_unmax("$VAR", alpha);
}
return Machine.exec_unify(args[1], res);
}
private static Number walk_max(String functor, Object first) {
List stack = null;
Number res = Integer.valueOf(-1);
for (; ; ) {
first = Store.deref(first);
if (Store.is_structure(first)) {
if (functor.equals(((Store.Structure) first).functor) &&
((Store.Structure) first).args.length == 1) {
Object peek = Store.deref(((Store.Structure) first).args[0]);
if (Machine.is_integer(peek)) {
if (eval.integer_compare(res, (Number) peek) < 0)
res = (Number) peek;
first = null;
}
}
if (first != null) {
if (!Store.is_compound(((Store.Structure) first).functor)) {
((Store.Structure) first).functor = new Store.Compound(
((Store.Structure) first).functor, Machine.VOID_ARGS);
if (0 != ((Store.Structure) first).args.length - 1) {
Store.Item item = new Store.Item((Store.Structure) first, null, 0);
stack = Store.stack_push(stack, item);
}
first = ((Store.Structure) first).args[0];
continue;
}
}
}
Store.Item item = (Store.Item) Store.stack_peek(stack);
if (item == null) {
return res;
} else {
item.idx++;
first = item.first.args[item.idx];
if (item.idx == item.first.args.length - 1)
Store.stack_pop(stack);
}
}
}
private static void walk_unmax(String functor, Object first) {
List stack = null;
for (; ; ) {
first = Store.deref(first);
if (Store.is_structure(first)) {
if (functor.equals(((Store.Structure) first).functor) &&
((Store.Structure) first).args.length == 1) {
Object peek = Store.deref(((Store.Structure) first).args[0]);
if (Machine.is_integer(peek)) {
first = null;
}
}
if (first != null) {
if (Store.is_compound(((Store.Structure) first).functor)) {
((Store.Structure) first).functor = ((Store.Structure) ((Store.Structure) first).functor).functor;
if (0 != ((Store.Structure) first).args.length - 1) {
Store.Item item = new Store.Item((Store.Structure) first, null, 0);
stack = Store.stack_push(stack, item);
}
first = ((Store.Structure) first).args[0];
continue;
}
}
}
Store.Item item = (Store.Item) Store.stack_peek(stack);
if (item == null) {
return;
} else {
item.idx++;
first = item.first.args[item.idx];
if (item.idx == item.first.args.length - 1)
Store.stack_pop(stack);
}
}
}
/******************************************************************/
/* call/2-4 */
/******************************************************************/
/**
* call(F, A1, .., An): [Corr.2 8.15.4.4]
* The predicate succeeds in calling the goal which results from
* appending the arguments A1, .., An to the callable F.
*/
private static Object special_calln(Object[] args) {
Object alpha = Store.deref(args[0]);
Object functor;
Object[] oldargs;
if (Store.is_structure(alpha)) {
functor = ((Store.Structure) alpha).functor;
oldargs = ((Store.Structure) alpha).args;
} else {
functor = alpha;
special.check_atomic(alpha);
oldargs = Machine.VOID_ARGS;
}
int arity = oldargs.length + args.length - 1;
Object goal;
if (arity == 0) {
goal = functor;
} else {
if (Machine.is_number(functor))
throw Machine.make_error(new Store.Compound("type_error",
new Object[]{"atom", functor}));
Object[] newargs = new Object[arity];
for (int i = 0; i < oldargs.length; i++)
newargs[i] = Store.deref(oldargs[i]);
for (int i = 0; i < args.length - 1; i++)
newargs[i + oldargs.length] = Store.deref(args[i + 1]);
goal = new Store.Compound(functor, newargs);
}
goal = new Store.Compound(".", new Object[]{goal,
((Store.Structure) Machine.call).args[1]});
Machine.cont(goal);
return Boolean.TRUE;
}
/******************************************************************/
/* Asm Lib Init */
/******************************************************************/
public static void main() {
Store.set("numbervars", 3, special.make_check(asmlib::test_numbervars));
Store.set("unnumbervars", 3, special.make_check(asmlib::test_unnumbervars));
Store.set("maxvars", 2, special.make_check(asmlib::test_maxvars));
Store.set("call", 2, special.make_special(asmlib::special_calln));
Store.set("call", 3, special.make_special(asmlib::special_calln));
Store.set("call", 4, special.make_special(asmlib::special_calln));
Store.set("call", 5, special.make_special(asmlib::special_calln));
Store.set("call", 6, special.make_special(asmlib::special_calln));
Store.set("call", 7, special.make_special(asmlib::special_calln));
Store.set("call", 8, special.make_special(asmlib::special_calln));
}
}

Use Privacy (c) 2005-2026 XLOG Technologies AG