// Souffle - A Datalog Compiler
// Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved
// Licensed under the Universal Permissive License v 1.0 as shown at:
// - https://opensource.org/licenses/UPL
// - <souffle root>/licenses/SOUFFLE-UPL.txt

//
// Compute Ackermann function
//

// attribute types
.type Integer <: symbol

// declarations
.decl succ (a:Integer, b:Integer)
.decl greaterThanZ(a:Integer)
.decl ack(a:Integer, b:Integer, c:Integer)
.output ack()

// IDB
ack("0", N, Ans) :-
    succ(N, Ans).

ack(M, "0", Ans) :-
    greaterThanZ(M),
    succ(X, M),
    ack(X, "1", Ans).

ack(M, N, Ans) :-
    greaterThanZ(M),
    greaterThanZ(N),
    succ(X, M),
    succ(Y, N),
    ack(M, Y, Ans2),
    ack(X, Ans2, Ans).

// EDB
succ("0", "1").
succ("1", "2").
succ("2", "3").
succ("3", "4").
succ("4", "5").
succ("5", "6").
succ("6", "7").
succ("7", "8").
succ("8", "9").
succ("9", "10").
succ("10", "11").
succ("11", "12").
succ("12", "13").
succ("13", "14").
succ("14", "15").
succ("15", "16").
succ("16", "17").
succ("17", "18").
succ("18", "19").
succ("19", "20").
succ("20", "21").

greaterThanZ("1").
greaterThanZ("2").
greaterThanZ("3").
greaterThanZ("4").
greaterThanZ("5").
greaterThanZ("6").
greaterThanZ("7").
greaterThanZ("8").
greaterThanZ("9").
greaterThanZ("10").
greaterThanZ("11").
greaterThanZ("12").
greaterThanZ("13").
greaterThanZ("14").
greaterThanZ("15").
greaterThanZ("16").
greaterThanZ("17").
greaterThanZ("18").
greaterThanZ("19").
greaterThanZ("20").
