2017-10-30 16 views
3

私は現在、expという自己生成型を受け入れ、算術演算(+ - * /)とシグマを行う関数を作っています。現在の作業状況は以下の通りです。進める方法はわかりません。例えばocamlで計算機を構築しました。シグマ関数の作り方はありません

type exp = X 
    | INT of int 
    | ADD of exp * exp 
    | SUB of exp * exp 
    | MUL of exp * exp 
    | DIV of exp * exp 
    | SIGMA of exp * exp * exp 

let rec calculator : exp -> int 
= fun e -> match e with 
| INT x -> x 
| ADD (e1, e2) -> calculator e1 + calculator e2 
| SUB (e1, e2) -> calculator e1 - calculator e2 
| MUL (e1, e2) -> calculator e1 * calculator e2 
| DIV (e1, e2) -> calculator e1/calculator e2 
| SIGMA (e1, e2, e3) -> let start = calculator e1 in 
        let end = calculator e2 in 
        match start with 
        | x -> 
        | _ -> expr2 

、SIGMA(INT 1、INT 10、SUB(MUL(X、X)、INT 1))375

実は私は 'と呼ばれる本を参照していた結果を生成する必要があります当初」と参照コードからOCamlのは、(下記)に動作していないので、私は今続行することはできません...ここで

type expr = 
Num of int 
|Add of expr * expr 
|Subtract of expr * expr 
|Multiply of expr * expr 
|Divide of expr * expr 

let rec evaluate e = 
    match e with 
    | Num x -> x 
    | Add (e, e') -> evaluate e + evaluate e' 
    | Subtract (e, e') -> evaluate e - evaluate e' 
    | Multiply (e, e') -> evaluate e * evaluate e' 
    | Divide (e, e') -> evaluate e/evaluate e' 
+0

シグマとして合計?私はあなたが使っている言語について何も知らないが、ループを使ってすべての数字を要約できると思う。 –

+1

環境変数と変数バインディングを保持する必要があります。私は同様の質問に答えていると確信しています。だからあなたの 'calculator'や' evaluate'は環境を持っている追加の引数を必要とします。あなたの 'expr'型は変数の' Var of string'を追加する必要があります。 ' –

+0

' | x - > '句には式がありません。あなたは変数として' end'を使いますが、それはキーワードです。最後に、被除数を計算した結果がゼロの場合に何が起こるかを考えてみるとよいでしょう。 – gsg

答えて

1

が可能なソリューションです:

type exp = 
    | VAR of string 
    | INT of int 
    | ADD of exp * exp 
    | SUB of exp * exp 
    | MUL of exp * exp 
    | DIV of exp * exp 
    | SIGMA of exp * exp * exp * exp 

module SMap = Map.Make (String) 

let rec aux_sigma var b env e = 
    let rec aux env acc = 
    let v = SMap.find var env in 
    if v > b then acc 
    else 
     let res = calculator env e in 
     aux (SMap.add var (v + 1) env) (acc + res) 
    in aux env 0 

and calculator env = function 
    | VAR x -> SMap.find x env 
    | INT x -> x 
    | ADD (e1, e2) -> calculator env e1 + calculator env e2 
    | SUB (e1, e2) -> calculator env e1 - calculator env e2 
    | MUL (e1, e2) -> calculator env e1 * calculator env e2 
    | DIV (e1, e2) -> calculator env e1/calculator env e2 
    | SIGMA (var, e1, e2, e3) -> 
    match var with 
    | VAR x -> 
     let init = calculator env e1 in 
     let bound = calculator env e2 in 
     aux_sigma x bound (SMap.add x init env) e3 
    | _ -> assert false 

let e1 = SIGMA (VAR "X", INT 1, INT 10, SUB(MUL(VAR "X", VAR "X"), INT 1)) 

let() = Printf.printf "%d\n" (calculator SMap.empty e1) 

XコンストラクタをVAR of stringに変更しました.sigmasに複数の変数が必要な場合があり、コントロール変数として使用される変数が追加されている可能性があるためです。私がやったもう一つのことは、あなたの初期値があなたの限界より低くなければならない、あるいはプログラムが永遠に動くということです。

ソリューションの背後にある考え方は、バジーレが言ったように、あなただけの変更、それに関連する値に各変数をリンクし、aux_sigma機能だけで、その後、SIGMAに使用し、変数をインクリメント式にcalculatorを実行する環境を維持していますマップ内のそのバインディング。

関連する問題