从多个列表中删除项目

Remove item from multiple lists

我有一个子问题,其解决方案比我认为必要的解决方案大得多。

问题定义如下

从组 ID 介于 Y 和 Z 或 A 和 B 之间的所有组中删除 X

表示为伪查询它看起来像这样 Y,Z,A,B 设置为 0,1,3,4

remove(X, 
       [ period(0,1), period(3,4) ],
       [ 
          group(0, [ subgroup([_,_,X,_,_]), subgroup([X])]),
          group(1, [ subgroup([X])]),
          group(2, [ subgroup([_,_,X])]),
          group(3, [ subgroup([_,X,_])]),
          group(4, [ subgroup([X,_,_])])
       ], UpdatedGroups).

结果会是

UpdatedGroups = [ 
    group(0, [ subgroup([_,_,_,_]), subgroup([])]),
    group(1, [ subgroup([])]),
    group(2, [ subgroup([_,_,X])]),
    group(3, [ subgroup([_,_])]),
    group(4, [ subgroup([_,_])])
]

所以,我的解决方案是:

当当前周期的开始时间小于或等于当前周期的结束时间时,在组中删除 X,而 "incrementing" 一天的开始时间。重复直到没有更多的经期

删除群组中的 X 由 "looping" 所有群组完成,并检查它是否与句点匹配,如果匹配则将用户从子群组中移除,这同样由 "looping" 完成。

这是一个非常乏味但直接的解决方案,现在我的问题是我经常发现自己在做这样的事情,并且找不到以不太全面的方式来做到这一点的方法。

有没有比我的方法不涵盖 50 多行的方法?


已更新

非常感谢,代码变得更加清晰 - 它可能会更进一步,但现在实际上可以 post 这里(这有点修改 - 但逻辑在那里)

inPeriods(Day, [ period(Start,End) | _ ]) :- between(Start,End, Day).
inPeriods(Day, [ _ | RemainingPeriods ]) :- inPeriods(Day, RemainingPeriods).

ruleGroupsInPeriod(Periods, rulegroup(Day,_)) :- inPeriods(Day, Periods).

removeUserFromRelevantRuleGroups(UserId, Periods, RuleGroups, UpdatedRuleGroups) :-
    include(ruleGroupsInPeriod(Periods), RuleGroups, IncludedRuleGroups).
    exclude(ruleGroupsInPeriod(Periods), RuleGroups, ExcludedRuleGroups),
    maplist(updateRuleGroup(UserId), IncludedRuleGroups, UpdatedIncludedRuleGroups)
    append(UpdatedIncludedRuleGroups, ExcludedRuleGroups, UpdatedRuleGroups).

updateRuleGroup(UserId, rulegroup(X, RuleList), rulegroup(X, UpdatedRuleList)) :-
    maplist(updateRule(UserId), RuleList, UpdatedRuleList).

updateRule(UserId, rule(X, UserList), rule(X, UpdatedUserList)) :-
    delete(UserList, UserId, UpdatedUserList).

.

您描述的模式非常常见,所有严肃的 Prolog 系统都附带强大的 元谓词(即,其参数表示谓词的谓词),让您轻松描述这个和以灵活的方式处理许多其他常见情况,最多为您的具体关系使用一些简单的附加定义。

Richard O'Keefe 对 An elementary Prolog Library contains the descriptions and implementations of many such predicates, which are becoming increasingly available in all major Prolog implementations and also in the Prologue for Prolog 的提议。

特别是,你应该学习:

  • include/3
  • exclude/3
  • maplist/[2,3]

请注意,尽管许多描述的谓词是 不纯的,因为它们会破坏代码的声明属性。与真正的关系相反,您将无法在保持逻辑健全性的同时在所有方向上使用它们。

练习:上面提到的三个谓词中,哪一个(如果有的话)在其他一切都是纯的时候保留,哪个(如果有)不?