【问题标题】:How to generate a set of values for a set of boolean variables in Ocaml如何在 Ocaml 中为一组布尔变量生成一组值
【发布时间】:2019-06-07 17:09:24
【问题描述】:

假设我们有一个函数,它将一组布尔变量作为输入:bol1,bol2...boln。我们如何使用尽可能少的代码迭代所有可能的布尔赋值?我需要实现一个函数,该函数将输入一组两个布尔变量以及一个涉及变量的布尔表达式并创建一个真值表。如果你看我的代码,它很长。所以我想减少它。此外,我这样做的方式似乎是多余的,因为编译器发出警告说匹配案例 |Var v2 未用于代码中的所有匹配案例 |Var v2。

这是this link 中的练习 46/47:“定义一个函数 table2,它以两个变量(指定为参数)返回给定逻辑表达式的真值表。返回值必须是包含 ( value_of_a, balue_of_b, value_of_expr)。”

type bool_expr =
  | Var of string
  | Not of bool_expr
  | And of bool_expr * bool_expr
  | Or of bool_expr * bool_expr 

let table2 (v1 : string) (v2 : string ) (exp : bool_expr)= 
  let rec evaluate (bol1 : bool) (bol2 : bool) (expp : bool_expr) =
    match bol1, bol2 with
    |true, true -> (match expp with
        |Var v1 -> true
        |Var v2 -> true
        |Not q -> not (evaluate bol1 bol2 q )
        |And (q,w) -> (evaluate bol1 bol2 q) && (evaluate bol1 bol2 w)
        |Or (q, w) -> (evaluate bol1 bol2 q) || (evaluate bol1 bol2 w))
    |true, false -> (match expp with
        |Var v1 -> true
        |Var v2 -> false
        |Not q -> not (evaluate bol1 bol2 q )
        |And (q,w) -> (evaluate bol1 bol2 q) && (evaluate bol1 bol2 w)
        |Or (q, w) -> (evaluate bol1 bol2 q) || (evaluate bol1 bol2 w))
    |false, true -> (match expp with
        |Var v1 -> false
        |Var v2 -> true
        |Not q -> not (evaluate bol1 bol2 q )
        |And (q,w) -> (evaluate bol1 bol2 q) && (evaluate bol1 bol2 w)
        |Or (q, w) -> (evaluate bol1 bol2 q) || (evaluate bol1 bol2 w))
    |false, false -> (match expp with
        |Var v1 -> false
        |Var v2 -> false
        |Not q -> not (evaluate bol1 bol2 q )
        |And (q,w) -> (evaluate bol1 bol2 q) && (evaluate bol1 bol2 w)
        |Or (q, w) -> (evaluate bol1 bol2 q) || (evaluate bol1 bol2 w))
  in [(true,true, (evaluate true true exp));(true,false, (evaluate true false exp));(false,true, (evaluate false true exp));(false,false, (evaluate false false exp))]

以下是预期输出的示例:

table2 "a" "b" (And(Var "a", Or(Var "a", Var "b")));;

  • : (bool * bool * bool) 列表 = [(真实,真实,真实); (真、假、真); (假,真,假); (假,假,假)]

【问题讨论】:

  • 这个问题会不会更适合codereview.se?

标签: ocaml


【解决方案1】:

提示:尝试递归查看问题。

bool_values { b_0, b_1, .... b_n } =
  { T + bool_values { b_1. ... b_n } } +
  { F + bool_values { b_1. ... b_n } }

【讨论】:

    【解决方案2】:

    如果您不匹配 bol1 和 bol2 而只是使用它们,您可以将代码减少 4 倍。

    (match expp with
       | Var v1 -> bol1
       | Var v2 -> bol2
       ...
    

    二次匹配不是比较变量而是结构。匹配Var v1 将值 expp 绑定到一个新变量 v1。 Var v1Var v2 这两种情况具有相同的结构,并且永远不会到达第二种情况。

    要比较值,您必须编写:

    | Var v when v == v1 -> bol1
    | Var v when v == v2 -> bol2
    | Var v -> (* neigther v1 nor v2, what to do now? *)
    

    至于将其扩展到具有更多列的表,您将不得不使用递归以及列表或数组而不是元组。例如。 type table = ((bool list) * bool) list

    【讨论】:

      猜你喜欢
      • 2015-06-25
      • 1970-01-01
      • 2022-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-12
      • 1970-01-01
      • 2021-12-11
      相关资源
      最近更新 更多