* If Term is a variable, it is printed using write/2.
* If Term is a nonvariable or an attributed variable, then portray(Stream, Term) is called. If it succeeds, so does print/2. Otherwise, if Term is atomic, it is written using write/2 and the predicate succeeds. If Term is a compound term, its main functor is printed using write/2 and print/2 is called recursively on its arguments.
Note that when this predicate is used to print a list, only the elements of the list, i.e. the heads, are passed to the recursive calls of print/2, but not the list tails. Thus e.g. a list [1,2,3] will be passed once to portray/2 as a whole and then the elements 1, 2, 3, but not [2,3],  and .
If portray/2 is not visible but portray/1 is, it is called instead of portray/2, with the 'output' stream temporarily redirected to Stream. Because of this side effect, defining portray/2 is preferrable.
portray/1, 2 is used by the system when printing the answer bindings in the top-level loop, and by the debugger to print trace lines.
print(S, Term) is equivalent to write_term(S, Term, [portrayed(true), numbervars(true)]).
As usual, the output is buffered, so it may need to be flushed (e.g. explicitly using flush/1).
Note The output of print/2 is not necessarily in a form acceptable to read/1,2 and there is no 'printq' predicate.
Success: ?- [user]. portray(S, a) :- write(S, b). p(a). user compiled 148 bytes in 0.00 seconds yes. ?- write(write(a)), nl, print(output, print(a)). write(a) print(b) yes. ?- trace. yes. Debugger switched on - creep mode ?- p(a). (1) 0 CALL p(a) (dbg)?- output: write ('o' typed) (1) 0 CALL p(a) (dbg)?- output: display (1) 0 CALL p(a) (dbg)?- output: print/writeq (1) 0 CALL p(b) (dbg)?- creep (1) 0 EXIT p(b) (dbg)?- creep yes. Error: print(S, a(b,c)). (Error 4). print("str", a(b,c)). (Error 5). print(input, X). (Error 192). print(nostr, X + 2). (Error 193).