# My Prolog code runs forever

**URL:** <https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665>\
**Category:** Help!\
**Tags:** bug, swish, discussion, how-to, chatgpt\
**Created:** [June 28, 2023, 11:36am UTC](https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665 "2023-06-28T11:36:50Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![berataltuntash](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/berataltuntash/32/5589_2.png) [@berataltuntash](https://swi-prolog.discourse.group/u/berataltuntash)\
**Post date:** [June 28, 2023, 11:36am UTC](https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665/1 "2023-06-28T11:36:50Z")

</div>

I have a code that suppose to solve a crossword puzzle (find all combinations to the crossword puzzle from given txt file. I got a little help from the chatgpt but couldnt solve my problem. It tooks forever to run and never gives an output. Code is as follows:  
:- style\_check(-singleton).  
 Read the words from a file Read the words from a file  
read\_words(Words) :-  
open(‘words.txt’, read, Stream),  
read\_words(Stream, Words),  
close(Stream).

read\_words(Stream, [Word | Rest]) :-  
+ at\_end\_of\_stream(Stream),  
read(Stream, Term),  
Term =… [\_, Word],  
read\_words(Stream, Rest).

read\_words(\_, ).

% Check if two words intersect at a given position  
intersect(Word1, Word2, Pos1, Pos2) :-  
nth1(Pos1, Word1, Char1),  
nth1(Pos2, Word2, Char2),  
Char1 = Char2.

% Solve the crossword puzzle  
solve\_puzzle(WordLengths, Intersections, Words) :-  
read\_words(AllWords),  
find\_words(WordLengths, AllWords, Words),  
check\_intersections(Words, Intersections),  
Words = [Word0, Word1, Word2, Word3, Word4],  
nth1(2, Word0, LastChar0),  
nth1(2, Word1, LastChar1),  
LastChar0 = LastChar1,  
nth1(4, Word0, SecondChar2),  
nth1(2, Word2, SecondChar2),  
nth1(3, Word2, LastChar3),  
nth1(1, Word4, LastChar3).

Find words of specified lengths find\_words([], \_, []). find\_words([Length | RestLengths], AllWords, [Word | RestWords]) :- member(Word, AllWords), atom\_length(Word, Length), Length =\< 6, Maximum word length constraint  
find\_words(RestLengths, AllWords, RestWords),  
length(RestWords, NumRestWords),  
NumRestWords \< 10. % Limit the number of generated words to 10

% Check if words satisfy intersection constraints  
check\_intersections(, \_).  
check\_intersections([Word | RestWords], Intersections) :-  
check\_word\_intersections(Word, RestWords, Intersections),  
check\_intersections(RestWords, Intersections).

% Check if a word satisfies intersection constraints with other words  
check\_word\_intersections(\_, , \_).  
check\_word\_intersections(Word, [Word2 | RestWords], Intersections) :-  
member([Pos1, Pos2, Pos3, Pos4], Intersections),  
nth1(Pos1, Word, Char1),  
nth1(Pos2, Word2, Char2),  
nth1(Pos3, Word3, Char3),  
nth1(Pos4, Word4, Char4),  
Char1 = Char2,  
Char1 = Char3,  
Char1 = Char4,  
check\_word\_intersections(Word, RestWords, Intersections).

% Entry point predicate  
grid(WordLengths, Intersections, Words) :-  
solve\_puzzle(WordLengths, Intersections, Words).

for example I am trying to run grid([5,3,4,4,3], [[0,1,1,2],[0,3,2,1],[2,3,3,2],[3,3,4,0]], Words). but it doesnt give an output.

---

<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:** [June 28, 2023, 4:32pm UTC](https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665/2 "2023-06-28T16:32:32Z")

</div>

Usual reminder: You can step through your program, to see exactly what is happening and where it is going wrong, using e.g. `trace.` - [SWI-Prolog -- Manual](https://www.swi-prolog.org/pldoc/man?section=debugger)

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [June 28, 2023, 4:53pm UTC](https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665/3 "2023-06-28T16:53:03Z")

</div>

Also, if you enclose your code within triple back-ticks, then it becomes more readable (using “markdown”). I had to make quite a few edits to what you posted to get this:

```prolog
read_words(Stream, [Word | Rest]) :-
    \+ at_end_of_stream(Stream),
    read(Stream, Term),
    Term =.. [_, Word],
    read_words(Stream, Rest).
read_words(_, []).

```

and I’d rewrite it this way:

```prolog
read_words(Stream, []) :-
    at_end_of_stream(Stream),
    !.
read_words(Stream, [Word | Rest]) :-
    read(Stream, Term),
    Term =.. [_, Word],
    read_words(Stream, Rest).

```

(although the code feels a bit strange … read/2 can handle list of words like `[foo, bar, something].`

---

<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:** [June 28, 2023, 5:00pm UTC](https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665/4 "2023-06-28T17:00:48Z")

</div>

> [@peter.ludemann](#):
>
> ```prolog
> read_words(Stream, []) :-
> at_end_of_stream(Stream),
> !.
> 
> ```

That is not _steadfast_. Can use:

```prolog
    read_words(Stream, Rest1),
    Rest1 = Rest.

```

… which allows the potential for JIT indexing on the 2nd arg of `read_words/2`.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [June 28, 2023, 6:22pm UTC](https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665/5 "2023-06-28T18:22:29Z")

</div>

> [@brebs](#):
>
> That is not _steadfast_

Is this better?

```prolog
read_words(Stream, Words) :-
    ( at_end_of_stream(Stream)
    -> Words = []
    ; read(Stream, Term),
        Term =.. [_, Word],
        Words = [Word|Rest],
        read_words(Stream, Rest)
    ).

```

---

<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:** [June 28, 2023, 7:03pm UTC](https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665/6 "2023-06-28T19:03:27Z")

</div>

> [@peter.ludemann](#):
>
> Is this better?

Yeah, it’s steadfast.

My inspiration is: [Prolog project issue with GNU Prolog - Stack Overflow](https://stackoverflow.com/a/76509286/)

---

<div class="post-metadata">

**Author:** ![anon419083](https://avatars.discourse-cdn.com/v4/letter/a/53a042/32.png) [@anon419083](https://swi-prolog.discourse.group/u/anon419083)\
**Post date:** [June 28, 2023, 7:24pm UTC](https://swi-prolog.discourse.group/t/my-prolog-code-runs-forever/6665/7 "2023-06-28T19:24:38Z")

</div>

If you aren’t a super expert, and you want at least to start to understand how prolog works, I would also suggest to use the trace facility. There is also a graphical version which is invoked with `?- gtrace.`. Both versions help a lot in understanding where prolog actually does something which is different from what you had in mind
