评估OCaml中所有可能的解释

时间:2011-03-08 13:16:50

标签: logic ocaml combinations

我需要评估两个公式是否相同。在这里,我使用公式的简单定义,这是一个前缀公式。

例如,And(Atom("b"), True)表示b and true,而And(Atom("b"), Or(Atom("c"), Not(Atom("c"))))表示(b and (c or not c))

我的想法很简单,获取所有原子,应用每个组合(对于我的情况,我将有4个组合,这些是真实的,真假的,假真的,假假的)。问题是,我不知道如何创建这些组合。

目前,我已经知道如何获得所有涉及原子,所以如果有5个原子,我应该创建32个组合。如何在OCaml中做到这一点?

2 个答案:

答案 0 :(得分:4)

好的,你需要的是一个函数combinations n,它将产生长度为n的所有布尔组合;让我们将它们表示为布尔列表的列表(即,单个变量赋值将是布尔值列表)。然后这个功能就可以了:

let rec combinations = function
  | 0 -> [[]]
  | n ->
    let rest = combinations (n - 1) in
    let comb_f = List.map (fun l -> false::l) rest in
    let comb_t = List.map (fun l -> true::l) rest in
    comb_t @ comb_f

只有一个长度为0的空组合,对于n > 0,我们会生成n-1的组合,并在其前加falsetrue来生成所有可能的长度为n的组合。

您可以编写一个函数来打印这样的组合,比如说:

let rec combinations_to_string = function
  | [] -> ""
  | x::xs ->
      let rec bools_to_str = function
        | [] -> ""
        | b::bs -> Printf.sprintf "%s%s" (if b then "T" else "F") (bools_to_str bs)
      in
      Printf.sprintf "[%s]%s" (bools_to_str x) (combinations_to_string xs)

然后用以下方法测试:

let _ =
  let n = int_of_string Sys.argv.(1) in
  let combs = combinations n in
  Printf.eprintf "combinations(%d) = %s\n" n (combinations_to_string combs)

得到:

> ./combinations 3
combinations(3) = [TTT][TTF][TFT][TFF][FTT][FTF][FFT][FFF]

答案 1 :(得分:1)

如果您将布尔值列表视为固定长度的位列表,则有一个非常简单的解决方案:计数!

如果你想拥有4个布尔值的所有组合,从0到15(2 ^ 4 - 1)计数 - 然后将每个位解释为一个布尔值。为简单起见,我将使用for循环,但您也可以使用递归:

let size = 4 in
(* '1 lsl size' computes 2^size *)
for i = 0 to (1 lsl size) - 1 do
   (* from: is the least significant bit '1'? *)
   let b0 = 1 = ((i / 1) mod 2) in
   let b1 = 1 = ((i / 2) mod 2) in
   let b2 = 1 = ((i / 4) mod 2) in
   (* to: is the most significant bit '1'? *)
   let b3 = 1 = ((i / 8) mod 2) in
   (* do your thing *)
   compute b0 b1 b2 b3
done

当然,你可以使循环的主体更加通用,以便它可以根据上面给出的大小等创建一个布尔列表/数组。 关键是您可以通过枚举要搜索的所有值来解决此问题。如果是这种情况,请计算直到问题大小的所有整数。编写一个函数,从整数生成原始问题的值。把它们放在一起。

此方法的优点是,在开始计算之前,需要先创建所有组合。对于大问题,这可能会拯救你。对于相当小的大小= 16,你将需要 65535 * sizeof(类型)内存 - 而且这个数量呈指数增长!上述解决方案只需要一定量的 sizeof(type)

为了科学的缘故:你的问题是 NP-complete ,所以如果你想要精确的解决方案,那将需要指数时间。