エレファント・ビジュアライザー調査記録

ビジュアルプログラミングで数式の変形を表すことを考えていくブロクです。

ラムダ計算と無限ラムダ多項式(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();