エレファント・コンピューティング調査報告

極限に関する順序を論理プログラミングの手法を使って指定することを目指すブロクです。

ラムダ計算と無限ラムダ多項式(7)

Calc クラスの RepeatGenerator と、それに必要な関数の文字列版です。

        private static Func<Exp, Exp> GetNextDecimalDigitAndNumbers = (Exp numbers) =>
            Exp.From("{" +
                "let (number, square_difference, scale) = numbers;" +
                "def maxdd (dd) =" +
                    "if dd >= 0 then { " +
                        "let zd = dd * 10^(-scale); " +
                        "let number_sq_diff = number * zd * 2 + zd * zd; " +
                        "if number_sq_diff <= square_difference then " +
                            "(dd, (number + zd, square_difference - number_sq_diff, scale + 1)) " +
                        "else " +
                            "maxdd(dd - 1) " +
                    "} else " +
                        "(0, (0, 0, 0)); " +
                "maxdd(9)" +
                "}").ExpEval(new Env("numbers", numbers));
        public static Func<Exp> GenerateDecimal = () =>
            Exp.From("{" +
                "let nums = (0, 3, 0); " +
                "let current_digit = 0; " +
                "def next() = {" +
                    "subst (current_digit, nums) = GetNextDecimalDigitAndNumbers(nums); " +
                    "true" +
                "};" +
                "def getCurrent() = current_digit; " +
                "def setCurrent(val) = {};" +
                "(next, getCurrent, setCurrent)" +
            "}").ExpEval(new Env("GetNextDecimalDigitAndNumbers", Exp.FuncExpExp(GetNextDecimalDigitAndNumbers)));
        public static Func<string> RepeatGenerator = () =>
            Exp.From("{" +
                "let generator = GenerateDecimal();" +
                "def GetNextDecimalDigit() = { generator.next(); generator.getCurrent() };" +
                "def repeat(number, e, count) = " +
                "if e < count " +
                        "then repeat(number + GetNextDecimalDigit() * 10^(-e), e + 1, count) " +
                        "else number;" +
                "repeat(0, 0, count)"+
            "}").ExpEval(new Env("count", Exp.Number(count), "GenerateDecimal", Exp.FuncExp(GenerateDecimal))).Print();