Python "fastlib"

Admin User, erstellt 18. Dez. 2023
         
###
# Modern Albufeira Prolog Interpreter
#
# 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.
##
from __main__ import (make_check, exec_build,
check_integer, unify, is_variable,
Compound, is_compound, add, make_error,
bind, atomic_equal, exec_unify, deref)
def test_numbervars(args):
alpha = exec_build(args[0])
beta = deref(exec_build(args[1]))
check_integer(beta)
if beta < 0:
raise make_error(Compound("domain_error",
["not_less_than_zero", beta]))
beta = numbervars(alpha, beta)
if beta is NotImplemented:
return False
return exec_unify(args[2], beta)
def numbervars(alpha, beta):
def numbervars2(alpha2):
nonlocal beta
while True:
alpha2 = deref(alpha2)
if is_variable(alpha2):
if not unify(alpha2, Compound("$VAR", [beta])):
beta = NotImplemented
else:
beta += 1
break
elif is_compound(alpha2):
alpha2 = alpha2.args
i = 0
while i < len(alpha2) - 1:
numbervars2(alpha2[i])
if beta is NotImplemented:
break
i += 1
alpha2 = alpha2[i]
else:
break
numbervars2(alpha)
return beta
def test_unify_checked(args):
alpha = exec_build(args[0])
beta = exec_build(args[1])
return unify_checked(alpha, beta)
def unify_checked(first, second):
while True:
first = deref(first)
second = deref(second)
if is_variable(first):
if is_variable(second) and first is second:
return True
if has_var(first, second):
return False
bind(second, first)
return True
if is_variable(second):
if has_var(second, first):
return False
bind(first, second)
return True
if not is_compound(first):
return atomic_equal(first, second)
if not is_compound(second):
return False
if len(first.args) != len(second.args):
return False
if first.functor != second.functor:
return False
first = first.args
second = second.args
i = 0
while i < len(first) - 1:
if not unify_checked(first[i], second[i]):
return False
i += 1
first = first[i]
second = second[i]
def has_var(term, source):
def has_var2(source2):
while True:
source2 = deref(source2)
if is_variable(source2):
return term is source2
elif is_compound(source2):
source2 = source2.args
i = 0
while i < len(source2) - 1:
if has_var2(source2[i]):
return True
i += 1
source2 = source2[i]
else:
return False
return has_var2(source)
def test_subsumes(args):
alpha = exec_build(args[0])
beta = exec_build(args[1])
return subsumes(alpha, beta)
def subsumes(first, second):
def subsumes2(first2, second2):
nonlocal second
while True:
first2 = deref(first2)
second2 = deref(second2)
if is_variable(first2):
if is_variable(second2) and first2 is second2:
return True
if has_var(first2, second):
return False
bind(second2, first2)
return True
if is_variable(second2):
return False
if not is_compound(first2):
return atomic_equal(first2, second2)
if not is_compound(second2):
return False
if len(first2.args) != len(second2.args):
return False
if first2.functor != second2.functor:
return False
first2 = first2.args
second2 = second2.args
i = 0
while i < len(first2) - 1:
if not subsumes2(first2[i], second2[i]):
return False
i += 1
first2 = first2[i]
second2 = second2[i]
return subsumes2(first, second)
def main():
add("numbervars", 3, make_check(test_numbervars))
add("unify_with_occurs_check", 2, make_check(test_unify_checked))
add("subsumes", 2, make_check(test_subsumes))