# Tabling: Problem with answer subsumption?

**URL:** <https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624>\
**Category:** Help!\
**Tags:** how-to\
**Created:** [July 11, 2020, 12:15am UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624 "2020-07-11T00:15:43Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [July 11, 2020, 12:15am UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/1 "2020-07-11T00:15:43Z")

</div>

I have a small grammar that turns a number sequence, say `1,2,3,4,9` into a range/integer list: 1-4,9

Here is the code:

```prolog
% :- table intrange_list(min,_,_). % Send bug report?

:- table intrange_list//1.
% Consolidate N, followed by (N+1)-H
intrange_list([L-H]) -->
   integer(L),
   `,`,
   { L #= L1 - 1 },
   intrange_list([L1-H]).

% Basic N,N+1 sequence
intrange_list([L-H]) -->
   integer(L),
   `,`,
   integer(H),
   { H #= L + 1 }.

% Sequence followed by sequence or integer.
intrange_list([L-H|Ls]) -->
   intrange_list([L-H]),
   `,`,
   intrange_list(Ls).

% Integer followed by sequence or integer or by itself.
intrange_list([i(N)|Ls]) -->
   integer(N),
   ( `,`, ! | [] ),
   intrange_list(Ls).

% End of list.
intrange_list([]) --> [].

```

Producing the following output:

```prolog
2 ?- phrase(intrange_list(L),`1,2,3,4,9`).
L = [i(1), i(2), i(3), i(4), i(9)] ;
L = [i(1), i(2), 3-4, i(9)] ;
L = [i(1), 2-3, i(4), i(9)] ;
L = [i(1), 2-4, i(9)] ;
L = [1-3, i(4), i(9)] ;
L = [1-2, i(3), i(4), i(9)] ;
L = [1-2, 3-4, i(9)] ;
L = [1-4, i(9)].

```

I want to keep only the shortest answer (taking advantage of term ordering), so instead of using regular tabling I switched to:

```prolog
:- table intrange_list(min,_,_). 

```

But now I get this error:

```prolog
5 ?- phrase(intrange_list(L),`1,2,3,4,9`).
ERROR: Uninstantiated argument expected, found [2-_16240]
ERROR: In:
ERROR: [21] throw(error(uninstantiation_error(...),_16290))
...

```

Answer subsumption is not accepting the partially uninitialized term `[2-_]`, why not allow partially uninstantiated terms?

Perhaps I am missing something.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 11, 2020, 7:51am UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/2 "2020-07-11T07:51:09Z")

</div>

> [@swi](#):
>
> Answer subsumption is not accepting the partially uninitialized term `[2-_]` , why not allow partially uninstantiated terms?

That is not the problem. The clue is in **Un** _instantiated_

> [@swi](#):
>
> `ERROR: Uninstantiated argument expected, found [2-_16240]`

The argument over which we do the answer subsumption must be unbound at call time. Anyway, it seems you want to minimize the list **length**. That is not going to work with standard order of term, which gives the list with the smallest first argument (and if equal the smallest second, etc.)

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [July 11, 2020, 1:11pm UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/3 "2020-07-11T13:11:48Z")

</div>

Thanks, I ended up using `aggregate_all/3` with `set(..)` and took the shortest (last) solution.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [July 11, 2020, 2:00pm UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/4 "2020-07-11T14:00:35Z")

</div>

Just out of curiosity, why not use an algorithm that gives you the shortest solution first instead of last? You might even just take the first and be done?

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [July 11, 2020, 7:06pm UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/5 "2020-07-11T19:06:14Z")

</div>

> [@Boris](#):
>
> st out of curiosity, why not use an algorithm that gives you the shortest solution first instead of last?

I just put together the DCG in a few minutes, but you’re right, do you have an idea for a better DCG?

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [July 11, 2020, 7:10pm UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/6 "2020-07-11T19:10:23Z")

</div>

It really depends what you are after. I thought this is just a minimal example that demonstrates a problem with tabling, and I don’t know about that so I assumed I am missing the big picture.

So is the problem "transform the string ‘1,2,3,4,9’ into the list `[1-4,i(9)]`"?

EDIT: and do you know that the original list of numbers is monotonically increasing? This makes it a bit easier I think.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 11, 2020, 7:12pm UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/7 "2020-07-11T19:12:16Z")

</div>

> [@swi](#):
>
> do you have an idea for a better DCG?

This is not a DCG answer.

Have you looked at [Run Length Encoding](https://en.wikipedia.org/wiki/Run-length_encoding) which is very similar. There is [working Prolog code for RLE](https://www.rosettacode.org/wiki/Run-length_encoding#Prolog) at RosettaCode.

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [July 11, 2020, 7:15pm UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/8 "2020-07-11T19:15:56Z")

</div>

> [@Boris](#):
>
> So is the problem "transform the string ‘1,2,3,4,9’ into the list `[1-4,i(9)]` "?

The problem is transform a sequence of integers into a string such that:

1. Any consecutive set of integers is shortened to Low-High
2. All the other integers are left in place

EDIT: I need it to work both ways.

This is very similar to what Eric pointed out: run length encoding.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [July 11, 2020, 7:38pm UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/9 "2020-07-11T19:38:48Z")

</div>

> [@swi](#):
>
> EDIT: I need it to work both ways.

Too difficult for me, sorry. I never learned how to do that.

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [July 11, 2020, 9:45pm UTC](https://swi-prolog.discourse.group/t/tabling-problem-with-answer-subsumption/2624/10 "2020-07-11T21:45:20Z")

</div>

Thanks Boris, you encourage me to put little bit more work, here is a version that works both ways (for the first answer) and gives the shortest answer first.

```prolog
intlist_intranges([L-H|Ls]) -->
   { N1 #= L + 1 },
   [L],
   lookahead(N1),
   intlist_intranges([N1-H|Ls]).

intlist_intranges([L-H|Ls]) -->
   { H #= L + 1 },
   [L],
   [H],
   intlist_intranges(Ls).

intlist_intranges([i(I)|Ls]) -->
   [I],
   intlist_intranges(Ls).

intlist_intranges([]) --> [].

lookahead(A), [A] --> [A].

```
