2017-05-16 20 views
5

Tôi đang sử dụng một Liên minh phân biệt để xác định biểu thức đại số, và sau đó thực hiện chức năng đơn giản hóa thực hiện Đơn giản hóa đại số cơ bản bằng thuật toán Match-Case đệ quy. Tôi chạy vào một rào cản liên quan đến lồng nhau cộng/trừ/phép nhân.Sử dụng Liên minh phân biệt đối xử để thực hiện Đơn giản đại số cơ bản F #

Vấn đề là trường hợp khớp để cộng/trừ/etc hai hoặc nhiều đối tượng Expression lồng nhau sẽ không đơn giản hóa tất cả các đường xuống một hằng số khi cần. IE:

simplify Add(Add(Const(1), Const(2)), Add(Const(1), Const(2)))

Trả về một đối tượng Expression chứa Add(Const(3), Const(3)) khi nó phải trả lại một chứa Const(6)

Các mã sau đây sẽ làm cho những gì đang xảy ra rất rõ ràng, cho ngắn gọn tôi chỉ bao gồm các trường hợp để bổ sung, kể từ khi cấu trúc (và vấn đề) giống hệt nhau cho phép trừ và phép nhân:

// Expression type 
type Expression = 
    | X 
    | Y 
    | Const of float 
    | Neg of Expression 
    | Add of Expression * Expression 
    | Sub of Expression * Expression 
    | Mul of Expression * Expression 

let rec simplify expr = 
    match expr with 
    | X -> expr 
    | Y -> expr 
    | Const(n) -> Const(n) 
    | Add(X, Const(0.0)) -> X 
    | Add(Const(0.0), X) -> X 
    | Add(Const(0.0), Y) -> Y 
    | Add(Y, Const(0.0)) -> Y 
    | Add(Const(n1), Const(n2)) -> Const(n1+n2)     // PROBLEM_1 
    | Add(expr1, expr2) -> Add(simplify(expr1), simplify(expr2)) // PROBLEM_2 

Vấn đề là bằng cách này nó hiện được cấu trúc, một đầu vào khớp với // PROBLEM_2 sẽ không đơn giản hóa hoàn toàn về trường hợp // PROBLEM_1, ngay cả khi expr1expr2 chỉ chứa các giá trị Const. Như đã đề cập ở trên, nó cuối cùng sẽ trả về một Expression chứa -> Add(Const(n2), Const(n2)) thay vì thực sự thêm hai giá trị cuối cùng với nhau như trong -> Const(n1+n2)

tôi có thể thay đổi như thế theo cách này được cấu trúc để Add(expr1, expr2) sẽ trả về một đơn Const trong trường hợp rằng tất cả các biểu thức con chứa và có thể được giảm xuống thành các giá trị Const, tức là: không chứa biến hoặc biểu thức không thể sai được?

Trả lời

5

Tôi nghĩ rằng dòng cuối cùng thay đổi để

| Add(expr1, expr2) -> simplify(Add(simplify(expr1), simplify(expr2))) 
//      ^^^^^^^^^         ^

là thay đổi duy nhất cần thiết?

+0

Chính xác là như vậy. Nó đã gây ra một số vấn đề khác, nhưng bây giờ tôi biết vấn đề là gì và có thể tiến lên phía trước. – user3776749

Các vấn đề liên quan