1

解決策が必要と思われるものよりもはるかに大きい副問題があります。

問題は次のように定義されます

グループが Y と Z または A と B の間の ID を持つすべてのグループから 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 をグループで削除し、開始日を「増分」します。生理がなくなるまで繰り返す

グループ内の X の削除は、すべてのグループを「ループ」してピリオドと一致するかどうかを確認することによって行われ、一致する場合はサブグループからユーザーを削除します。これも「ループ」によって行われます。

これは非常に面倒ですが、簡単な解決策です。現在、私の問題は、このようなことを頻繁に行っていることに気づき、包括的でない方法でこれを行うためのアプローチを見つけることができないことです。

50行以上をカバーしない私のアプローチ以外のアプローチはありますか?


更新しました

どうもありがとう、コードはとてもきれいになりました - もっと先に進むかもしれませんが、実際にここに投稿することが可能になりました (これは少し変更されています - しかしロジックはそこにあります)

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).
4

1 に答える 1

2

はい

あなたが説明するパターンは非常に一般的であり、すべての深刻な Prolog システムには強力なメタ述語(つまり、引数が述語を表す述語) が付属しています。具体的な関係の追加定義。

基本的な Prolog ライブラリに関するRichard O'Keefe の提案には、すべての主要な Prolog 実装およびProlog の Prologue でますます利用可能になっている、多くのそのような述語の記述と実装が含まれています。

特に、次のことを学ぶ必要があります。

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

ただし、説明されている述語の多くは、コードの宣言的なプロパティを破壊するという意味で不純であることに注意してください。真の関係とは対照的に、論理的な健全性を維持しながら、それらをあらゆる方向に使用することはできません。

演習: 上記の 3 つの述語のうち、他のすべてが純粋である場合に

于 2016-02-08T18:56:37.787 に答える