我正在尝试使用SBV 库(版本 7.12)解决以下涉及 Haskell 中祖先关系的 csp :
给我所有不是斯蒂芬后裔的人的集合。
我的解决方案(见下文)出现以下异常
*** Exception: SBV.Mergeable.List: No least-upper-bound for lists of differing size (1,0)
问题:是否可以使用 SBV/使用 SMT 求解器来解决这样的约束,如果 - 我需要如何制定问题?
我的解决方案尝试:
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveAnyClass #-}
module Main where
import Data.SBV
data Person
= Mary
| Richard
| Claudia
| Christian
| Stephen
mkSymbolicEnumeration ''Person
-- symbolic shorthands for person constructors
[mary, richard, claudia, christian, stephen] =
map literal [Mary, Richard, Claudia, Christian, Stephen]
childOf :: [(Person, Person)]
childOf = [
(Mary, Richard) ,
(Richard, Christian),
(Christian, Stephen)]
getAncestors :: Person -> [Person]
getAncestors p = go childOf p []
where
go [] _ acc = nub acc
go ((p1, p2): rels) a acc
| p1 == p = go rels p (p2:acc) ++ getAncestors p2
| otherwise = go rels a acc
-- symbolic version of getAncestors
getSAncestors :: SBV Person -> [SBV Person]
getSAncestors p = ite (p .== mary) (map literal (getAncestors Mary))
$ ite (p .== richard) (map literal (getAncestors Richard))
$ ite (p .== claudia) (map literal (getAncestors Claudia))
$ ite (p .== christian) (map literal (getAncestors Christian))
(map literal (getAncestors Stephen))
cspAncestors :: IO AllSatResult
cspAncestors = allSat $ do
(person :: SBV Person) <- free_
constrain $ bnot $ stephen `sElem` (getSAncestors person)
提前谢谢了!