У меня есть подзадача, для которой решение намного больше, чем я предполагаю.Удалить элемент из нескольких списков
Проблема определяется следующим образом
Удалить X из всех групп, где группа имеет идентификатор между Y и Z или А и В
выражается в виде псевдо запроса он выглядит как это с 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).
Отлично! 'nowOneMoreThingThatIsMissingIs'' using_more_readable_names'! 'unReadableNamesLikeInJava' в порядке для * переменных *, но соглашение Prolog для * predicate * names' is_to_use_underscores_between_words'. – mat
Также избегайте использования * императивов *, например, «обновление» и «удаление». Вместо этого опишите ** отношение ** между сущностями, например 'user_groups_without',' rules_updated' и т. Д. Поиск хороших имен - это тяжело и стоит того! – mat