给定 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 中的变量列表,生成所有真值赋值的列表?的主要内容,如果未能解决你的问题,请参考以下文章