심규민
가입: 2010년 10월 2일 올린 글: 21
|
올려짐: 2010년11월12일 15:51 주제: [HW6-4] ae를 정리해주는 함수 |
|
|
toStr : ae -> string
주어진 ae를 일정한 형식으로 정리해줍니다.
isSame : ae * ae -> bool
두 ae를 정리하여 비교합니다.
많이 이용해주세요.
정상 작동은 보장 못합니다
코드: |
type ae = Const of int
| Var of string
| Power of string * int
| Times of ae list
| Sum of ae list
(* diff here *)
type be = Atom of ae
| And of be * be
| Or of be * be
let rec translate e =
match e with
Const _ -> Atom e
| Var _ -> Atom e
| Power _ -> Atom e
| Times [] -> Atom (Const 1)
| Times (h::t) -> And (translate h, translate (Times t))
| Sum [] -> Atom (Const 0)
| Sum (h::t) -> Or (translate h, translate (Sum t))
let rec expand e =
match e with
Atom _ -> e
| And (Or (l, r), b) -> Or (expand (And (expand l, expand b)), (expand (And (expand r, expand b))))
| And (a, Or (l, r)) -> Or (expand (And (expand a, expand l)), (expand (And (expand a, expand r))))
| And (l, r) -> if (expand l, expand r) = (l, r) then And (l, r) else expand (And (expand l, expand r))
| Or (l, r) -> Or (expand l, expand r)
exception Error
let rec flatten e =
let rec flatA e =
match e with
Atom a -> [a]
| And (a, b) -> (flatA a) @ (flatA b)
| _ -> raise Error
in
match e with
Atom a -> [[a]]
| And _ -> [(flatA e)]
| Or (l, r) -> (flatten l) @ (flatten r)
let sortcompo e =
let compare a b =
match (a, b) with
(Const _, Power _) -> true
| (Power _, Const _) -> false
| (Power (s, _), Power (t, _)) -> s < t
| _ -> true
in
List.map (fun x -> Sort.list compare x)
(List.map (fun x -> List.map (fun y -> match y with Var s -> Power (s, 1) | _ -> y) x) e)
let simplify e =
let rec shrinkc e =
match e with
((Const a)::(Const b)::tl) -> shrinkc (Const (a * b)::tl)
| _ -> e
in
let rec shrinkp e =
match e with
((Power (s, n))::(Power (t, m))::tl) -> if s = t then shrinkp ((Power (s, n + m))::tl)
else ((Power (s, n))::(shrinkp ((Power (t, m))::tl)))
| ((Const a)::tl) -> ((Const a)::(shrinkp tl))
| _ -> e
in
let zerone e =
List.map (fun x -> match x with ((Const _)::_) -> x | _ -> (Const 1)::x)
(List.filter (fun x -> match x with ((Const 0)::tl) -> false | _ -> true) e)
in
zerone (List.map (fun x -> shrinkp (shrinkc x)) e)
module StringSet = Set.Make(String);;
let allvar e =
let rec flat e =
match e with
[] -> []
| (h::t) -> h @ (flat t)
in
Sort.list (fun x y -> x < y)
(StringSet.elements (List.fold_left (fun x y -> match y with Power(s, n) -> StringSet.add s x | _ -> x) StringSet.empty (flat e)))
let formalize (e, v) =
let sub (var, tl) =
List.fold_left (fun prev elt -> match elt with Power(s, n) -> if s = var then n else prev | _ -> prev) 0 tl
in
List.map (fun x -> match x with (Const n)::tl -> n::(List.map (fun var -> sub (var, tl)) v) | _ -> raise Error) e
let decend e =
let rec compare x y =
match (x, y) with
(a::[], b::[]) -> false
| (a::hx::tx, b::hy::ty) -> if hx < hy then true
else if hx > hy then false
else compare (a::tx) (b::ty)
| _ -> raise Error
in
Sort.list compare e
let rec sameterm e =
match e with
(ha::ta)::(hb::tb)::tl -> if ta = tb then sameterm (((ha + hb)::ta)::tl)
else (ha::ta)::(sameterm ((hb::tb)::tl))
| _ -> e
let toStr e =
let s = simplify (sortcompo (flatten (expand (translate e)))) in
let v = allvar s in
let rec sum e =
let rec times (e, v) =
match e with
[] -> ""
| h::t -> (if h = 0 then "" else "(" ^ (List.hd v) ^ "^" ^ (string_of_int h) ^ ")") ^ (times (t, List.tl v))
in
match e with
h::[] -> ((string_of_int (List.hd h)) ^ (times (List.tl h, v)))
| h::t -> ((string_of_int (List.hd h)) ^ (times (List.tl h, v))) ^ " + " ^ (sum t)
| _ -> "0"
in
sum (List.filter (fun x -> (List.hd x) <> 0) (sameterm (decend (formalize (s, v)))))
let isSame (a, b) =
(toStr a) = (toStr b)
|
코드: |
# let ae4=Times[Sum[Times[Const 2;Power("x",2)];Var "x";Var "y"];Sum[Times[Const 5;Power("x",2);Var "y"];Power("y",2)]];;
val ae4 : ae =
Times
[Sum [Times [Const 2; Power ("x", 2)]; Var "x"; Var "y"];
Sum [Times [Const 5; Power ("x", 2); Var "y"]; Power ("y", 2)]]
# toStr(ae4);;
- : string = "1(y^3) + 1(x^1)(y^2) + 7(x^2)(y^2) + 5(x^3)(y^1) + 10(x^4)(y^1)"
# toStr(diff(ae4,"x"));;
- : string = "1(y^2) + 14(x^1)(y^2) + 15(x^2)(y^1) + 40(x^3)(y^1)"
# toStr(diff(ae4,"y"));;
- : string = "3(y^2) + 2(x^1)(y^1) + 14(x^2)(y^1) + 5(x^3) + 10(x^4)"
# isSame(Sum[Var"x";Const 2;Times[Const (-1);Const 2]], Power("x", 1));;
- : bool = true
|
심규민 가 2010년11월15일 18:16에 수정함, 총 1 번 수정됨 |
|