As a non-functional property the sharing is observable. You can try the following:

```
p(A, B, C, D, E) :-
D = f(E,E,E,E),
C = f(D,D,D,D),
B = f(C,C,C,C),
A = f(B,B,B,B).
```

If you do a Logtalk source transformation you get a clause of size 4^4+4^3+4^2+4^1 = 340 memory cells. If you don’t do a Logtalk source transformation you get a clause of size 5*4 = 20 memory cells.

Same for the runtime, i.e. the thread time use by calling for example:

```
?- p(Y,_,_,_,X).
```

I didn’t test yet, since I don’t have a souce transformer. Maybe I can add some timing comparison by using a manual transformation. This is observable if the Prolog system doesn’t apply some common subexpression elimination while compiling clauses.

Common subexpressions elimination would possibly need hash calculation and 340 head searches, and would slow down assert and retract, so I don’t have this. Thats why I call it **explicit** sharing. Its not an automatism. Its something that the programmer can do by using (=)/2.

A modified Logtalk transformation could possibly only move the terms to the head up to some depth. But to not negatively affect deep indexing it would need some good heuristics here. This is not yet a problem in my Prolog system, since I don’t have yet deep indexing.

**Edit 02.01.2019:**

Here are some timings, pretty much the ratio 340 cell/20 cell from slow to fast:

```
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.16)
/* with sharing */
?- time((between(1,1000000,_),p(Y,_,_,_,X),fail;true)).
% 1,999,999 inferences, 0.266 CPU in 0.254 seconds (104% CPU, 7529408 Lips)
true.
/* without sharing */
?- time((between(1,1000000,_),p2(Y,_,_,_,X),fail;true)).
% 1,999,999 inferences, 3.297 CPU in 3.289 seconds (100% CPU, 606635 Lips)
true.
```

I used the following manually transformed p/5:

```
?- listing(p2/5).
p2(f(f(f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A))), f(f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A))), f(f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A))), f(f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)))), f(f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A))), f(f(A, A, A, A), f(A, A, A, A), f(A, A, A, A),
f(A, A, A, A)), f(A, A, A, A), A).
```