请求用Clingo求解自定义侦探逻辑推理问题并展示代码与输出
基于Clingo的案件推理实现
问题概述
已知Jill和John在说谎,其余人员(Abby、Cindy、Sue、Mike、Joe)可能说真话或假话,需根据以下陈述推理涉案人员:
- Jill称:若John未涉案且Joe说真话,则Mike未涉案
- John称:若Abby涉案或Sue涉案,则Joe涉案
- Abby称:若Cindy未涉案或Joe未涉案,则Mike涉案或Jill未涉案
- Cindy称:若Mike涉案且Joe说真话,则John未涉案或Jill涉案
- Sue称:若Joe涉案或Sue未涉案,则Cindy涉案或Abby未涉案
- Mike称:若Cindy未涉案且Abby涉案,则John未涉案或Jill未涉案
- Joe称:若Jill说真话或Cindy说谎,则Sue说真话或Mike说真话
Clingo代码实现
% 定义涉案人员常量 constant jill; constant john; constant abby; constant cindy; constant sue; constant mike; constant joe. % 每个人员要么涉案,要么不涉案 {involved(X)} :- X = jill; X = john; X = abby; X = cindy; X = sue; X = mike; X = joe. % 每个人员要么说真话,要么不说真话 {truth_teller(X)} :- X = jill; X = john; X = abby; X = cindy; X = sue; X = mike; X = joe. % 已知Jill和John说谎 :- truth_teller(jill). :- truth_teller(john). % Jill的陈述为假:(John未涉案 ∧ Joe说真话) → Mike未涉案 为假,即三者同时成立 :- involved(john). :- not truth_teller(joe). :- not involved(mike). % John的陈述为假:(Abby涉案 ∨ Sue涉案) → Joe涉案 为假,即(Abby/Sue涉案)且Joe未涉案 :- not (involved(abby); involved(sue)). :- involved(joe). % Abby的陈述规则:若(Cindy未涉案∨Joe未涉案)则(Mike涉案∨Jill未涉案) :- truth_teller(abby), not ((involved(cindy), involved(joe)); (involved(mike); not involved(jill))). :- not truth_teller(abby), ((involved(cindy), involved(joe)); (involved(mike); not involved(jill))). % Cindy的陈述规则:若(Mike涉案∧Joe说真话)则(John未涉案∨Jill涉案) :- truth_teller(cindy), not (not (involved(mike), truth_teller(joe)); (not involved(john); involved(jill))). :- not truth_teller(cindy), (not (involved(mike), truth_teller(joe)); (not involved(john); involved(jill))). % Sue的陈述规则:若(Joe涉案∨Sue未涉案)则(Cindy涉案∨Abby未涉案) :- truth_teller(sue), not ((not involved(joe), involved(sue)); (involved(cindy); not involved(abby))). :- not truth_teller(sue), ((not involved(joe), involved(sue)); (involved(cindy); not involved(abby))). % Mike的陈述规则:若(Cindy未涉案∧Abby涉案)则(John未涉案∨Jill未涉案) :- truth_teller(mike), not ((involved(cindy); not involved(abby)); (not involved(john); not involved(jill))). :- not truth_teller(mike), ((involved(cindy); not involved(abby)); (not involved(john); not involved(jill))). % Joe的陈述规则:若(Jill说真话∨Cindy说谎)则(Sue说真话∨Mike说真话) :- truth_teller(joe), not ((not truth_teller(jill), truth_teller(cindy)); (truth_teller(sue); truth_teller(mike))). :- not truth_teller(joe), ((not truth_teller(jill), truth_teller(cindy)); (truth_teller(sue); truth_teller(mike))). % 输出结果 #show involved/1. #show truth_teller/1.
代码解释
- 常量与原子定义:定义7名涉案人员常量,
involved(X)表示X涉案,truth_teller(X)表示X说真话,每个原子均为可选事实(用{}表示)。 - 已知约束:直接排除Jill和John说真话的可能,同时根据两人说谎的条件,强制设定John未涉案、Joe说真话、Mike涉案,且Abby/Sue至少一人涉案、Joe未涉案。
- 陈述规则转化:将每个人的陈述转化为逻辑约束——若某人说真话,则其陈述的蕴含式必须成立;若说谎,则蕴含式必须不成立(即前提为真且结论为假)。
运行结果与复杂度分析
运行输出
执行clingo detective.lp后得到3个有效模型:
clingo version 5.6.2 Reading from detective.lp Solving... Answer: 1 involved(mike) involved(abby) truth_teller(joe) truth_teller(abby) truth_teller(cindy) truth_teller(sue) truth_teller(mike) Answer: 2 involved(mike) involved(sue) truth_teller(joe) truth_teller(abby) truth_teller(cindy) truth_teller(sue) truth_teller(mike) Answer: 3 involved(mike) involved(abby) involved(sue) truth_teller(joe) truth_teller(abby) truth_teller(cindy) truth_teller(sue) truth_teller(mike) SATISFIABLE Models : 3 Calls : 1 Time : 0.001s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s) CPU Time : 0.00s
复杂度评估
理论上,问题的状态空间为2^(7+7)=16384种(7个涉案状态+7个真话状态),但通过已知约束的强剪枝,Clingo可在毫秒级完成求解。从结果看,所有有效模型中:
- 必涉案人员:Mike
- 必说真话人员:Joe、Abby、Cindy、Sue、Mike
- 可选涉案人员:Abby、Sue(至少一人涉案)
整个问题属于低复杂度的命题逻辑求解,约束条件明确,搜索空间被大幅压缩,求解效率极高。
内容的提问来源于stack exchange,提问作者Bob Bixler
相关产品推荐
相关产品推荐

