给定 SML 中的变量列表,生成所有真值赋值的列表?

Posted

技术标签:

【中文标题】给定 SML 中的变量列表,生成所有真值赋值的列表?【英文标题】:Generating a list of all truth assignments given a list of variables in SML? 【发布时间】:2021-11-24 08:16:11 【问题描述】:

我正在尝试在 SML 中编写一个函数,它给定一个变量列表,它返回每个可能的布尔赋值的元组列表。

基本上,我希望代码这样做:

fun allAssignments ["p", "q"] = 
  [[("p", True),  ("q", True) ]
   [("p", True),  ("q", False)]
   [("p", False), ("q", True) ]
   [("p", False), ("q", False)]]

然而,我写了这个函数,虽然它对我来说很有意义,但我不断收到 tycon mismatch 错误,我无法纠正它:

fun allAssignments nil = [[]]
  | allAssignments (x::xs) = [(x, true)::allAssignments xs] @ [(x, false)::allAssignments xs]

谁能帮我指出正确的方向?谢谢!

【问题讨论】:

【参考方案1】:

根据您的示例,allAssignments 需要具有 string list -> (string * bool) list list 类型(或者可能是 'a list -> ('a * bool) list list''a list -> (''a * bool) list list,但为简单起见,我将坚持使用 string;两种方式的实现都是相同的) .

因此,allAssignments xs 必须具有 (string * bool) list list 类型,而 (x, true) 必须具有 string * bool 类型。但是(x, true) :: allAssignments xs 是类型不匹配,因为:: 期望它的第二个参数是一个列表,其元素的类型与其第一个参数相同,而在您的情况下,第二个参数是一个列表,其元素是 lists (第一个参数不是)。

如果我们设想一个不检查类型的标准机器学习版本,您的allAssignments 版本将给出以下结果:

allAssignments [][[]] allAssignments ["q"][[("q", true), []], [("q", false), []]] allAssignments ["p", "q"][[("p", true), [("q", true), []], [("q", false), []]], [("p", false), [("q", true), []], [("q", false), []]]]

如您所见,它并没有真正奏效。一个问题是"q" 的赋值比"p" 的赋值嵌套在更多级别的列表中(因此出现类型错误)。另一个问题是("p", true)("p", false)每个只出现一次,而("q", true)("q", false)每个出现两次。

要解决此问题,您需要实际“打开”allAssignments xs 并将 (x, true) 添加到它包含的每个单独列表中,然后对 (x, false) 进行相同操作。

这是一种方法,使用map

fun allAssignments nil = [nil]
 |  allAssignments (x::xs) =
      (map (fn assignments => (x, true) :: assignments) (allAssignments xs))
      @ (map (fn assignments => (x, false) :: assignments) (allAssignments xs))

虽然我应该提到这个实现并不是最优的;计算时间和内存使用都可以显着减少,特别是如果您不关心分配返回的顺序。

【讨论】:

啊,这很有道理!非常感谢您的帮助! @NessEarthbound:我的荣幸!

以上是关于给定 SML 中的变量列表,生成所有真值赋值的列表?的主要内容,如果未能解决你的问题,请参考以下文章

char列表上的SML模式匹配

如何比较和搜索列表中的元素与列表 SML 中的元组

SML 中的一个对列表进行切片的函数?

生成真/假的所有长度-n 排列?

使用循环为列表中的变量赋值

从 Prolog 到 Haskell 的思考——生成真值组合列表