Simulang - a simulation language
Simulang - シミュレーション言語
Simulang - 仿真语言
Alpha Lab
The virtual machine and ASM for running program of Simulang have been finished, please download and test them:
Simulangのプログラムを実行するための仮想マシンとASMをすでに完了しています、ダウンロードしてテストしてください:
目前已经写完运行Simulang程序所需的虚拟机和ASM,请下载并测试:
 
http://up.x0000.net/files/TSimulang.zip
 
The implementation with C# and F# class library, instead of the "language" of Simulang, is like this:
Simulangという「言語」ではなく、C#やF#でのクラス ライブラリによる実装は、そのコードは下記の感じです:
并非必须使用Simulang "语言",也可以使用C#和F#的类库实现,代码如下所示:
simulation template library in C#:
C#でのシミュレーション ライブラリです:
C# simulation 模板库:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

// The "equation" lib extended this simulation lib:
// さらに、「方程式」のライブラリです:
// 进一步,"方程"类库:
// http://x0000.net/topic.aspx?id=3738-0

// A UI library using this simulation lib:
// このsimulation libを使ったUIライブラリです:
// 应用了此simulation库的UI类库:
// http://x0000.net/topic.aspx?id=3688-0

// The conversion between imperative and functional description of state:
// 状態の手順的と関数的な表記の相互変換:
// 状态的命令式和函数式描述的互转:
// http://x0000.net/topic.aspx?id=3744-0

namespace Simulation
{
    interface IUpdate
    {
        void Update();
        void Flush();
    }

    class Manager
    {
        public static Manager TheManager = new Manager();
        private LinkedList<IUpdate> Updates = new LinkedList<IUpdate>();
        public void Add(IUpdate update)
        {
            Updates.AddLast(update);
        }
        public void Update()
        {
            foreach(IUpdate i in Updates)
                i.Update();
        }
        public void Flush()
        {
            foreach(IUpdate i in Updates)
                i.Flush();
        }
    }
 
    interface IVar<T>
    {
        T v();
    }

    class CachedVar<T> : IVar<T>, IUpdate
    {
        private Func<T> FuncValue;
        private T Value;
        private bool Calculated;
        public CachedVar(Func<T> funcValue)
        {
            FuncValue = funcValue;
            Calculated = false;
            Manager.TheManager.Add(this);
        }
        public T v()
        {
            if (Calculated)
                return Value;
            else
            {
                Calculated = true;
                return Value = FuncValue();
            }
        }
        public void Update(){}
        public void Flush()
        {
            Calculated = false;
        }
    }

    class State<T> : IVar<T>, IUpdate
    {
        private Func<T,T> FuncState;
        private T Current, Next;
        public State(T defaultValue, Func<T,T> funcState)
        {
            Current = defaultValue;
            FuncState = funcState;
            Manager.TheManager.Add(this);
        }
        public T v()
        {
            return Current;
        }
        public void Update()
        {
            Next = FuncState(Current); 
        }
        public void Flush()
        {
            Current = Next;
        }
    }
}

a sample of C# (a simulation of the sun and the earth):
C#のサンプルです(太陽と地球のシミュレーション):
C#例子(太阳地球仿真):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Simulation;

namespace SimulationCSharp
{
    public partial class Form1 : Form
    {
        bool Exit = false;

        struct Vec
        {
            public double X, Y;
            public Vec(double x, double y) { X = x; Y = y; }
            public double Norm() { return Math.Sqrt(X * X + Y * Y); }
            public static Vec operator +(Vec v1, Vec v2) { return new Vec(v1.X + v2.X, v1.Y + v2.Y); }
            public static Vec operator -(Vec v1, Vec v2) { return new Vec(v1.X - v2.X, v1.Y - v2.Y); }
            public static Vec operator *(double k, Vec v) { return new Vec(k * v.X, k * v.Y); }
            public static Vec operator *(Vec v, double k) { return new Vec(v.X * k, v.Y * k); }
            public static Vec operator /(Vec v, double k) { return new Vec(v.X / k, v.Y / k); }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private double AU = 149597870691; // m
        private double Year = 3600 * 24 * 365.256363004;
        private double G = 6.67300e-11; // m3*kg-1*s-2
        private double M = 1.98892e30; // kg mass of sun
        private double m = 5.9742e24; // kg mass of earth
        private Vec vm0 = new Vec(30287, 0); // m/s speed at perihelion

        double TScale = 3600 * 24 * 7;
        double dt;
        long t1 = DateTime.Now.Ticks / 1000000;

        State<Vec> sM;
        State<Vec> sm;
        State<Vec> vM;
        State<Vec> vm;

        CachedVar<Vec> r_mM;
        CachedVar<Vec> r_Mm;
        CachedVar<Vec> gm;
        CachedVar<Vec> gM;

        private void Form1_Load(object sender, EventArgs e)
        {
            r_mM = new CachedVar<Vec>(() => sM.v() - sm.v());
            r_Mm = new CachedVar<Vec>(() => sm.v() - sM.v());
            gm = new CachedVar<Vec>(() => G * M * r_mM.v() / Math.Pow(r_mM.v().Norm(), 3));
            gM = new CachedVar<Vec>(() => G * m * r_Mm.v() / Math.Pow(r_Mm.v().Norm(), 3));

            sM = new State<Vec>(new Vec(0.0, 0.0), (x) => x + vM.v() * dt);
            sm = new State<Vec>(new Vec(0.0, 0.9832898912 * AU), (x) => x + vm.v() * dt); // the perihelion
            vM = new State<Vec>(new Vec(0.0, 0.0), (x) => x + gM.v() * dt);
            vm = new State<Vec>(vm0, (x) => x + gm.v() * dt);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Exit = true;
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            while (Exit == false)
            {
                long t2 = DateTime.Now.Ticks / 1000000;
                dt = TScale * Math.Min(t2 - t1, 0.05);
                t1 = t2;

                Manager.TheManager.Update();

                btnSun.Left = this.Width / 2 + (int)(100.0 * sM.v().X / AU);
                btnSun.Top = this.Height / 2 - (int)(100.0 * sM.v().Y / AU);
                btnEarth.Left = this.Width / 2 + (int)(100.0 * sm.v().X / AU);
                btnEarth.Top = this.Height / 2 - (int)(100.0 * sm.v().Y / AU);

                Manager.TheManager.Flush();

                Application.DoEvents();
            }
        }
    }
}

simulation template library in F#:
F#でのシミュレーション ライブラリです:
F# simulation 模板库:

namespace Simulation

    open System
    open System.Collections.Generic

    type IUpdate = interface
        abstract Update : unit -> unit
        abstract Flush : unit -> unit
    end

    module Manager =
        let Updates = new LinkedList<IUpdate>()
        let Add (update : IUpdate) = ignore (Updates.AddLast update)
        let Update () = for i in Updates do i.Update()
        let Flush () = for i in Updates do i.Flush()

    type IVar<'T> = interface
        abstract v : unit -> 'T
    end

    type CachedVar<'T> = class
        interface IVar<'T> with
            member x.v () =
                if x.Calculated then
                    x.Value
                else
                    x.Calculated <- true
                    x.Value <- x.FuncValue ()
                    x.Value
        end
        interface IUpdate with
            member x.Update () = ()
            member x.Flush () = x.Calculated <- false
        end
        val mutable FuncValue : unit -> 'T
        [<DefaultValue>]
        val mutable Value : 'T
        val mutable Calculated : bool
        new (funcValue : unit -> 'T) as x =
            {
                FuncValue = funcValue;
                Calculated = false
            }
            then
                Manager.Add x
    end

    type State<'T> = class
        interface IVar<'T> with
            member x.v () = x.Current
        end
        interface IUpdate with
            member x.Update () = x.Next <- x.FuncState x.Current
            member x.Flush () = x.Current <- x.Next
        end
        val mutable FuncState : 'T -> 'T
        val mutable Current : 'T
        [<DefaultValue>]
        val mutable Next : 'T
        new (defaultValue : 'T, funcState : 'T -> 'T) as x =
            {
                Current = defaultValue;
                FuncState = funcState
            }
            then
                Manager.Add x
    end