# ------------------
# Ackermann function
# ------------------
#
# The Ackermann function, holds paramount significance in theoretical
# computer science and computability theory. Formulated by Wilhelm
# Ackermann, it stands as a fundamental example illustrating functions
# that transcend primitive recursion, showcasing the existence of
# computable problems that defy conventional algorithmic approaches.
# Its rapid growth, even for small inputs, makes it a powerful tool in
# complexity theory, establishing lower bounds on computational
# complexity and emphasizing the inherent challenges in designing
# efficient algorithms for certain problems. The Ackermann function’s
# prominence extends to symbolize the limits of computability, playing
# a crucial role in delineating what can and cannot be algorithmically
# computed within the theoretical realms of computer science.
#
# One can see the rapid growth in
# https://github.com/eyereasoner/eye/blob/master/reasoning/ackermann/ackermann-answer.n3
# where A(4,0) has a value of 2 digits, A(4,1) has a value of 5 digits
# and A(4,2) has a value of 19729 digits.

@prefix math: <http://www.w3.org/2000/10/swap/math#>.
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix var: <http://www.w3.org/2000/10/swap/var#>.
@prefix : <http://example.org/#>.

# ackermann(x, y)
[ log:graph (
    [ log:triple ((var:X var:Y) :ackermann var:A)]
)] log:isImpliedBy [ log:graph (
    [ log:triple ((var:Y 3) math:sum var:B)]
    [ log:triple ((var:X var:B 2) :ackermann var:C)]
    [ log:triple ((var:C 3) math:difference var:A)]
)].

# ackermann(x, y, z)
# succ (x=0)
[ log:graph (
    [ log:triple ((0 var:Y var:Z) :ackermann var:A)]
)] log:isImpliedBy [ log:graph (
    [ log:triple(true log:callWithCut true)]
    [ log:triple ((var:Y 1) math:sum var:A)]
)].

# sum (x=1)
[ log:graph (
    [ log:triple ((1 var:Y var:Z) :ackermann var:A)]
)] log:isImpliedBy [ log:graph (
    [ log:triple(true log:callWithCut true)]
    [ log:triple ((var:Y var:Z) math:sum var:A)]
)].

# product (x=2)
[ log:graph (
    [ log:triple ((2 var:Y var:Z) :ackermann var:A)]
)] log:isImpliedBy [ log:graph (
    [ log:triple(true log:callWithCut true)]
    [ log:triple ((var:Y var:Z) math:product var:A)]
)].

# exponentiation (x=3), tetration (x=4), pentation (x=5), hexation (x=6), etc
[ log:graph (
    [ log:triple ((var:X 0 var:Z) :ackermann 1)]
)] log:isImpliedBy [ log:graph (
    [ log:triple(true log:callWithCut true)]
)].

[ log:graph (
    [ log:triple ((var:X var:Y var:Z) :ackermann var:A)]
)] log:isImpliedBy [ log:graph (
    [ log:triple ((var:Y 1) math:difference var:B)]
    [ log:triple ((var:X var:B var:Z) :ackermann var:C)]
    [ log:triple ((var:X 1) math:difference var:D)]
    [ log:triple ((var:D var:C var:Z) :ackermann var:A)]
)].

# query
[ log:graph (
    [ log:triple ((0 0) :ackermann var:A0)]
    [ log:triple ((0 6) :ackermann var:A1)]
    [ log:triple ((1 2) :ackermann var:A2)]
    [ log:triple ((1 7) :ackermann var:A3)]
    [ log:triple ((2 2) :ackermann var:A4)]
    [ log:triple ((2 9) :ackermann var:A5)]
    [ log:triple ((3 4) :ackermann var:A6)]
    [ log:triple ((3 14) :ackermann var:A7)]
    [ log:triple ((4 0) :ackermann var:A8)]
    [ log:triple ((4 1) :ackermann var:A9)]
    [ log:triple ((4 2) :ackermann var:A10)]
)] log:impliesAnswer [ log:graph (
    [ log:triple ((0 0) :ackermann var:A0)]
    [ log:triple ((0 6) :ackermann var:A1)]
    [ log:triple ((1 2) :ackermann var:A2)]
    [ log:triple ((1 7) :ackermann var:A3)]
    [ log:triple ((2 2) :ackermann var:A4)]
    [ log:triple ((2 9) :ackermann var:A5)]
    [ log:triple ((3 4) :ackermann var:A6)]
    [ log:triple ((3 14) :ackermann var:A7)]
    [ log:triple ((4 0) :ackermann var:A8)]
    [ log:triple ((4 1) :ackermann var:A9)]
    [ log:triple ((4 2) :ackermann var:A10)]
)].
