plazm February 2016
### Remove item from multiple lists

I have a subproblem for which the solution is way larger than what I would suspect is necessary.

The problem is defined as follows

**Remove X from all groups where group has id between Y and Z or A and B**

expressed as a pseudo query it looks like this with Y,Z,A,B set to 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).
```

The result will be

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

So, my solution to this is:

While start of current period is less than or equal end of current period, do removal of X in groups, while "incrementing" start of day. Repeat until no more periods

The removal of X in groups is done by "looping" all groups and check if it matches the period, and if it does remove the user from subgroups, which again is done by "looping".

This is a very tedious but straight forward solution, now my problem is that I quite often find myself doing stuff like this, and cannot find approaches to do this in a less comprehensive way.

Are there other approaches than mine that does not cover 50+ lines?

**Updated**

Thanks a lot, the code became so much cleaner - it might go further, but now it is possible to actually post here (this is modified a bit - but the logic is there)

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

```
```

```
```

```
```### Answers

mat February 2016
**Yes**.

The pattern you describe is very common, and all serious Prolog systems ship with powerful **meta-predicates** (i.e., predicates whose arguments denote predicates) that let you easily describe this and many other common situations in a flexible manner, using at most a few simple additional definitions for your concrete relations.

Richard O'Keefe's proposal for **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**.

In particular, you should study:

`include/3`

`exclude/3`

`maplist/[2,3]`

Note though that many of the described predicates are **impure** in the sense that they will destroy declarative properties of your code. In contrast to true relations, you won't be able to use them in all directions while preserving logical soundness.

**Exercise**: Which of the three predicates mentioned above, if any, preserve logical-purity when everything else is pure, and which, if any, do not?

```
```#### Post Status

Asked in February 2016

Viewed 1,929 times

Voted 12

Answered 1 times
#### Search

## Leave an answer

```
```

```
```