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

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

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

C# で以下のような式を書くことができるようにします。

Exp.Number ( 数値 )

数値を表します。「数値」は整数、文字列、または BigNum です。

Exp.Bool ( 真理値 )

真理値を表します。

Exp.String ( 文字列 )

文字列を表します。

Exp.Name ( 文字列 )

変数名などの名前、または演算子を表します。

Exp.Func ( 関数名, 引数リスト ) または Exp.Func ( 関数名, 引数, 引数, … , 引数 )

関数を実行します。関数名は名前または関数を表す式です。

Exp.Let ( 変数名, 式 )

変数に式の値を代入します。

Exp.Subst ( 変数名, 式 )

すでに存在する変数に式の値を代入します。

Exp.If ( 式(条件), 式(真のとき), 式(偽のとき) )

「式(条件)」が真のとき「式(真のとき)」、「式(偽のとき)」が評価されます。

Exp.Define ( 関数名, 変数名リスト, 式 )

関数を定義します。

Exp.From ( 文字列 )

式を表す文字列で式を作ります。

new ExpBlock { 式, 式, … , 式 }

式を順の実行します。

new ExpList { 式, 式, … , 式 }

式のリストを表します。

new NameList { 式, 式, … , 式 }

名前のリストを表します。

ExpBlock、ExpList、NameList は以下のようなクラスを継承したものです。こうすると上記のような書き方ができます。

    internal class GenList<T> : IEnumerable<T>
    {
        private List<T> list;
        public GenList()
        {
            list = new List<T>();
        }
        public IEnumerator<T> GetEnumerator()
        {
            return list.GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        public void Add(T x)
        {
            list.Add(x);
        }
        public IEnumerable<(T, U)> Zip<U>(GenList<U> list2)
        {
            for (int i = 0; i < list.Count && i < list2.list.Count; i++)
            {
                yield return (list[i], list2.list[i]);
            }
        }
    }

足し算
        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("123.456")),
                Exp.Let("y", Exp.Number("12.34")),
                Exp.Let("z", Exp.Func("+", Exp.Name("x"), Exp.Name("y"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: 135.796

引き算
        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("123.456")),
                Exp.Let("y", Exp.Number("12.34")),
                Exp.Let("z", Exp.Func("-", Exp.Name("x"), Exp.Name("y"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: 111.116

        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("123.456")),
                Exp.Let("y", Exp.Number("12.34")),
                Exp.Let("z", Exp.Func("-", Exp.Name("y"), Exp.Name("x"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: -111.116

掛け算
        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("123.456")),
                Exp.Let("y", Exp.Number("12.34")),
                Exp.Let("z", Exp.Func("*", Exp.Name("x"), Exp.Name("y"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: 1523.44704

整数の割り算の商
        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("1234")),
                Exp.Let("y", Exp.Number("12")),
                Exp.Let("z", Exp.Func("/", Exp.Name("x"), Exp.Name("y"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: 102

整数の割り算の余り
        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("1234")),
                Exp.Let("y", Exp.Number("12")),
                Exp.Let("z", Exp.Func("%", Exp.Name("x"), Exp.Name("y"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: 10

整数の整数乗
        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("12")),
                Exp.Let("y", Exp.Number("3")),
                Exp.Let("z", Exp.Func("^", Exp.Name("x"), Exp.Name("y"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: 1728

10 の整数乗
        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("10")),
                Exp.Let("y", Exp.Number("3")),
                Exp.Let("z", Exp.Func("^", Exp.Name("x"), Exp.Name("y"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: 1000

        public static Func<string> Test = () =>
            new ExpBlock {
                Exp.Let("x", Exp.Number("10")),
                Exp.Let("y", Exp.Number("-3")),
                Exp.Let("z", Exp.Func("^", Exp.Name("x"), Exp.Name("y"))),
                Exp.Name("z") 
            }.ExpEval(new Env()).Print();

結果: 0.001