# Turning failure based loop into DCG recursion

**URL:** <https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316>\
**Category:** General\
**Created:** [March 18, 2024, 3:04pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316 "2024-03-18T15:04:12Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 18, 2024, 3:04pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/1 "2024-03-18T15:04:12Z")

</div>

Hello,

I have a simple failure based loop that backtracks over all solutions of a predicate. The loop is part of an export routine with a header and the failure based loop exporting a table one row at a time.

I’d like to use DCG instead, but can’t figure out how to “advance” backtracked solution in DCG …

Something like this:

export\_all :- open\_file(Out), print\_header(Out), print\_lines(Out), close\_file(Out).

instead i want:

export\_all → open\_file(Out), print\_header(Out), print\_lines(Out), close\_file(Out).  
open\_file → { open\_file(Out) }  
print\_header(Out) → {print\_header(Out}  
print\_lines → {print\_line(Out), print\_lines(Out)}  
close\_file(Out) → close\_file(Out).

print\_line(Out) :- get\_line(Line), format(Out, ‘~w’, [Line]).

So, how do I advance get\_line(Line) via backtracking and while letting the DCG do the backtracking.

any thoughts would be great.

Dan

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [March 18, 2024, 3:59pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/2 "2024-03-18T15:59:34Z")

</div>

> [@grossdan](#):
>
> print\_lines →

Add another `print_lines` predicate, and another `print_line` predicate, for when the end of the file is reached.

Simple example: [SWI-Prolog predicate for reading in lines from input file - Stack Overflow](https://stackoverflow.com/a/31469396)

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 18, 2024, 4:21pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/3 "2024-03-18T16:21:53Z")

</div>

Thank you.

I don’t grasp it … with external input there seems to be some lazy read – i.e. the next read state is handled by each read.

Whereas within prolog what advances to the next line in get\_line(Line) …

Note: get\_line(Line) basically recalls prolog facts.

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [March 18, 2024, 5:00pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/4 "2024-03-18T17:00:47Z")

</div>

> [@grossdan](#):
>
> Note: get\_line(Line) basically recalls prolog facts.

In that case, a DCG won’t work.

Could use e.g. forall/2 to loop over the facts.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 18, 2024, 5:10pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/5 "2024-03-18T17:10:19Z")

</div>

I am not sure how forall could be used in combination with DCG …

Also, I rather want to avoid loading all solutions into memory just to get it to work with DCG

One idea i had was to look at lazy lists to turn a fact look up into a lazy list, in the hope that every new get\_line(Line) would retrieve a next fact from a lazy list … not sure if this can be done.

[https://www.swi-prolog.org/pldoc/doc/\_SWI\_/library/lazy\_lists.pl](https://www.swi-prolog.org/pldoc/doc/_SWI_/library/lazy_lists.pl)

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [March 18, 2024, 5:32pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/6 "2024-03-18T17:32:22Z")

</div>

> [@grossdan](#):
>
> want to avoid loading all solutions into memory

I think your scenario description is missing some pieces. Such as:

- What’s the data source? A text file?
- Why are you ending up with facts, to iterate through?

If your input is a text file, then presumably you want to write a DCG to parse the lines in that, and which also outputs the processed line, before moving on to the next line.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 18, 2024, 7:02pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/7 "2024-03-18T19:02:09Z")

</div>

Indeed, I now realize, I didn’t give full information – adding to confusion.

DCG can be used in more than one “mode”. Typically, DCG is used to parse input text. However, DCG can as well be used to generate output text.

In my case, i want to use DCG to specify an structure that generates for exporting tables into a file.

So, the source is the prolog internal fact base that DCG is supposed to read as it generates tables.

---

<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:** [March 18, 2024, 9:17pm UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/8 "2024-03-18T21:17:34Z")

</div>

There is foreach//2 and foreach//3. That might help you. But your questions are really hard to decipher. You don’t even use code blocks for your code…

```prolog
?- [user].
|: t(one). t(two). t(four).
|: ^D% user://1 compiled 0.00 sec, 3 clauses
true.

?- use_module(library(dcg/basics)), use_module(library(dcg/high_order)).
true.

?- portray_text(true).
true.

?- phrase(("header--", foreach(t(X), atom(X), ";"), "--footer"), Codes).
Codes = `header--one;two;four--footer`.

```

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 19, 2024, 1:30am UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/9 "2024-03-19T01:30:51Z")

</div>

thank you.

Could you deconstruct the example so it looks like a DCG declaration that is the parsed …

---

<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:** [March 19, 2024, 4:43am UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/10 "2024-03-19T04:43:44Z")

</div>

I do not understand your question 🤷🏻‍♂️

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 19, 2024, 4:51am UTC](https://swi-prolog.discourse.group/t/turning-failure-based-loop-into-dcg-recursion/7316/11 "2024-03-19T04:51:18Z")

</div>

Boris,

In your example you included DCG syntax inside of phrase, how would this look like if the syntax is placed external to phrase in the file.
