# Wiki: Prolog

Tips for golfing in Prolog on codegolf.stackexchange.com

### Handling arguments

Use `feature(argv,A)` or `'\$argv'(A)` instead of `prolog_flag(argv,A)`.
`'\$argv'(A)` has extra arguments at the beginning, you can filter them by index:

``````:-feature(argv,A),nth0(I,A,X),code(X).
:-'\$argv'(A),nth0(I,A,X),I>3,code(X).
``````

`unix(argv(A))` is equivalent to `'\$argv'(A)`, but arguments that are syntactically valid numbers are passed as a number. You can filter them using `number(X)` or `atom(X)`.

Because integers are less than atoms in the standard ordering of terms, `X@<''` (or maybe `X@<a` if you're really lucky) works as a shorter alternative to `number(X)`.

`re_split` with `/n` flag converts output atoms to numbers if possible:

``````:- S='2 3 4', re_split(' '/n,S,L), L=[2,' ',3,' ',4].
``````

### Iterating over an array

Instead of using `maplist` over an array, you can use `member` with careful backtracking. You can also use `nth0` or `nth1` to get the index of the element as well:

``````maplist(+,A). +A:-code.
member(V,A),code,0=1.
nth0(I,A,V),code,0=1.
nth1(I,A,V),code,0=1.
``````

### Printing

`format` can accept an arithmetic expression for numeric conversions.

``````:-X is 1+2,write(X).
:-format('~d',1+2).
``````
``````:-X is 1+2,writeln(X).
:-format('~d
',1+2).
``````

### Failing

``````:-member(X,[2,3]),write(X),0=1.
:-member(X,[2,3]),\+write(X).
``````

### Packing

Use backticks to get a list of character codes:

``````:- `0{ðž‰€` = [48,123,123456].
``````

Big numbers can be written using `<radix>'<number>` syntax or `0'<character>` syntax:

``````:- 36'PROLOG = 1558151872.
:- 0'ðž‰€ = 123456.
``````

Lists of one integer or one-character atom (e.g., `[97]`, ``a``, `[a]`), and strings of length 1 (e.g., `"a"`) in arithmetic expression are interpreted as integers:

``````:-X is 100.
:-X is 0'd.
:-X is"d".
``````

### Managing predicates

Predicates can be written using operators (CGSE for more details):

``````2+2. 1+b.
:-X+Y,write(X),\+write(Y). % prints '221b'
``````

You can add predicates dynamically using `assert`:

``````:-X=2,Y=3,assert(X+Y),2+3,write('success'),2+5,write('unreachable').
``````

### Generators

Some predicates generate solutions if the arguments are unbound:

``````nth0(X,_,_).  % between(X,0,inf)
nth1(X,_,_).  % between(X,1,inf)
``````

### Rational numbers

You don't need `rdiv` if at least one argument is rational:

``````:- X is 1/2r3. % X = 3r2
``````

A rational number literal, `rdiv` result, or the value of an arithmetic expression (if it's a rational number) is converted to an integer if possible:

``````:- X is 4r2,      Y is 1/X. % X = 2 (integer), Y = 0.5 (float)
:- X is 4 rdiv 2, Y is 1/X. % X = 2 (integer), Y = 0.5 (float)
:- X is 4r7/2r7,  Y is 1/X. % X = 2 (integer), Y = 0.5 (float)
:- X =  4r7/2r7,  Y is 1/X. % X = 4r7/2r7 (expression), Y = 1r2 (rational)
``````