OCaml令人满意的逻辑操作

时间:2016-11-06 12:02:49

标签: ocaml

我正在尝试在ocaml中编写一个函数,该函数将逻辑运算作为参数(如下定义:)

type oper = B of bool 
            | V of string
            | Neg of oper
            | And of oper * oper 
            | Or of oper * oper
            | Impl of oper * oper

如果操作可满足则返回“true”(至少在一种情况下返回true),如果不满足则返回“false”(在所有情况下都返回false)。为此,我试图用V true或B false替换V s,直到我得到true并引发Do_it异常。如果我在任何情况下都不成功,我会抛出Not_found异常并评估我在程序结束时得到的异常。

  let satisfable operation=
    let switch x var tf=
        let rec aux1 =function
          |B b->B b
          |V s when s=var ->aux1 (B tf)
          |V s->V s
          |And(e1,e2)->(match aux1 e1, aux1 e2 with
                       |(B false,_)|(_,B false)->B false
                       |(B true, x)|(x,B true)->aux1 x
                       |(x1,x2)->And(x1,x2))
          |Or(e1,e2)->(match aux1 e1,aux1 e2 with
                      |(B true, _)|(_,B true)->B true
                      |(B false, x)|(x,B false)->aux1 x
                      |(x1,x2)->Or(x1,x2))
          |Impl(e1,e2)->(match aux1 e1,aux1 e2 with
                    |(B false,_)->B false
                    |(B true,x)->aux1 x
                    |(x1,x2)->Impl(x1,x2))
          |Neg b->(match b with
                  |B b-> B (not b)
                  |s->Neg (aux1 s))
        in aux1 x    
    in let rec aux = function
         |B b->B b
         |V s->(match switch operation s true with
               |B true->raise Do_it
               |x-> aux (switch operation s true)
               )
         |V s->(match switch operation s false with
                |B true->raise Do_it
                |x-> aux (switch operation s false)
                )
         |V s->raise Not_found
          |And(e1,e2)->(match aux e1, aux e2 with
                       |(B false,_)|(_,B false)->B false
                       |(B true, x)|(x,B true)->aux x
                       |(x1,x2)->And(x1,x2))
          |Or(e1,e2)->(match aux e1,aux e2 with
                      |(B true, _)|(_,B true)->B true
                      |(B false, x)|(x,B false)->aux x
                      |(x1,x2)->Or(x1,x2))
          |Impl(e1,e2)->(match aux e1,aux e2 with
                    |(B false,_)->B false
                    |(B true,x)->aux x
                    |(x1,x2)->Impl(x1,x2))
          |Neg b->(match b with
                  |B b-> B (not b)
                  |s->Neg (aux s))
                     in if(try aux operation with Do_it->B true|Not_found->B false)=B false then false else true;;

但它不能按照我想要的方式工作,在某些情况下它甚至会引发Stack溢出异常。

函数“switch”返回一个操作,其中字符串变量“var”已替换为tf(true / false)的值

2 个答案:

答案 0 :(得分:2)

您的函数None正在使用aux的外部定义,该定义在每次递归调用时都不会更改。

答案 1 :(得分:1)

在函数aux中,您在V s上匹配三次。只会分析第一个案例。此外,调用两次switch operation s true并不是一个好主意,您可以通过声明let case_true = switch operation s true来避免重复两次相同的计算。