prologfactorialfailure-slice# Prolog factorial predicate

I have a factorial predicate`fact(N,F)`

, where either `N`

or `F`

or both are bounded to a number.

For example I can have `fact(3,F)`

or `fact(N,6)`

.
Here is my predicate, which works but I don't really understand how. I used `trace`

but still have problems understanding it.

```
fact(0,1).
fact(N,F) :-
fact(N1,F1),
N is N1 + 1,
F is N * F1.
```

Solution

You can try to go through your program step-by-step to understand what's going on. This will be very slow indeed, and quite unreliable. Or, you can instead let Prolog do (part of) the work. So the idea is to modify the program a bit and then look what Prolog thinks about it.

This is what I see when I look at your program - this is called a failure-slice

~~fact(0,1) :-~~. fact(N,F) :- fact(N1,F1),falsefalse,~~N is N1 + 1~~,~~F is N * F1~~.

When will this fragment terminate? Look at the remaining visible part! The `N`

only occurs once in the head: nobody is interested in the first argument! Same for the `F`

. Therefore: No matter what arguments you have, this program will not terminate. **And thus the same holds for your original program!**

In the original version this wasn't that clear. Watch out:

```
?- fact(29,F).
F = 8841761993739701954543616000000
```

At first this looks nice, but if you ask for the next answer (with SPACE or `;`

), you end up looping, i.e. waiting for an answer that never comes. Worse, false queries loop right away:

```
?- fact(29,1).
loops.
```

So how can you find these problems, without understanding precisely what is going on? This is what ** false** is for. A goal that is never true. If you add it like

`fact(29,F), `**false**.

you will never be distracted by beautiful answers.Why have you put all your arithmetics at the end? I suspect because you got some errors before. There is an easy way out to avoid all such errors:

```
:- use_module(library(clpfd)).
```

You can now write `#=`

instead of `is`

, and you need some restriction like `N #>= 1`

. Can I leave you there?

- Turbo Prolog: Create a palindrome by adding the smallest number of characters to the list
- Prolog order of clause body gives different results when using negation
- Problem With a Predicate to Check if X Occurs Exactly Four Times in a List
- Most General Unifier (Prolog)
- In prolog, functors vs predicates, and goals
- Solving N-queens with Constraint Handling Rules
- 'if' in prolog?
- Are there any Prolog compilers that can optimize by targeting specific queries?
- gprolog: Getting a stacktrace after an exception
- Efficient solution for the same-fringe problem for binary trees
- Understanding prolog \+ and the engine's solution space search
- Prolog, X element before element Y on list
- What is the difference between once and cut in prolog?
- Getting the seed set by the ECLiPSe on loading
- Get simple Prolog example to work
- How to do recursion in a L-system inspired rewrite System, without DCG
- Maximum number of atoms in SICStus Prolog 4
- How to create a list dynamically in Prolog?
- Prolog Syntax for Dependent Conditions
- Guard clauses in prolog?
- phrase_from_stream/2 nontermination (Stream from http_open/3)
- SWI-Prolog: [FATAL ERROR: Could not find system resources]
- DCG LaTeX printer for FOL prover
- Prolog: a person is a sibling of himself?
- When can I safely avoid storing temporary calculations in Prolog?
- Prolog - Solution of a riddle
- Is the structure of my Prolog expression isomorphic to the structure of the Liar Paradox?
- Syntax error: Operator expected in Prolog
- Assertion Failure in SWI-Prolog When Using pyswip to Consult a Prolog File
- Retract by partial match?