```    1:- module(punary, [
2	unary/1,
3    pow/3,
4    string_unary/2,
5    unary_string/2,
7    mul/3,
8    div/4
9]).   10
11:- use_module(purity).   12
13:- multifile purity:pcompare/4.   14
15purity:pcompare(punary, A, B, C) :- unary_compare(A, B, C).
16
17
18% unary(Unary).
19%
20% Unary is a valid unary number
21%
22unary(zero).
23unary(c(Z)) :- unary(Z).
24
25% unary_compare(Unary1, Unary2, Comparator).
26%
27% Comparator is the different type of Unary1 and Unary2
28% Comparator is one of =, <, or >
29%
30unary_compare(zero, U2, C) :- unary_compare_z(U2, C).
31unary_compare(c(Z), U2, C) :- unary_compare_c(U2, c(Z), C).
32
33unary_compare_z(zero, =).
34unary_compare_z(c(_), <).
35
36unary_compare_c(zero, _, >).
37unary_compare_c(c(Z2), c(Z1), C) :-
38	unary_compare(Z1, Z2, C).
39
41%
42% Sum is the value of UnaryA + UnaryB
43%
47
48% mul(UnaryA, UnaryB, Product)
49%
50% Product is the result of UnaryA * UnaryB
51%
52mul(zero, _, zero).
53mul(c(X), Y, R) :-
55	mul(X, Y, S).
56
57% div(Divide, By, Quotient, Remainder)
58%
59% division with remainder
60%
61div(S, D, Q, R) :-
62	unary_compare(zero, R, C),
63	unary_div(C, S, D, Q, R).
64
65unary_div(=, S, D, Q, zero) :-
66	mul(D, Q, S).
67unary_div(>, S, D, Q, zero) :-
68	mul(D, Q, S).
69unary_div(<, S, D, Q, R) :-
70	unary_compare(R, D, <),
72	mul(D, Q, Is).
73
74% upow(Unary, Factor, Power)
75%
76% Power is Unary^Factor
77%
78pow(zero, zero, zero).
79pow(N, c(zero), N).
80pow(N, c(c(Z)), R) :-
81    mul(N, R1, R),
82    pow(N, c(Z), R1).
83
84
85
86
87
88
89
90%
91% convert 0 - 9 into a unary value
92%
93d_to_u(U, N) :-
94	d_to_u_(['0','1','2','3','4','5','6','7','8','9'], N, U).
95
96d_to_u_([A|T], N, U) :-
97	pdif(pchar, A, N, C),
98	d_to_u_(C, N, T, U).
99
100d_to_u_(false, _, _, zero).
101d_to_u_(true, N, T, c(Z)) :-
102	d_to_u_(T, N, Z).
103
104%
105% convert a unary value below 10 into 0 - 9
106%
107u_to_d(U, D) :-
108	u_to_d_(U, ['0','1','2','3','4','5','6','7','8','9'], D).
109
110u_to_d_(zero, [D|_], D).
111u_to_d_(c(Z), [_|T], D) :-
112	u_to_d_(Z, T, D).
113
114% this is required for overlows, but is not a character that is used
115unary_10( c(c(c(c(c(c(c(c(c(c(zero)))))))))) ).
116
117%
118% Convert strings to unary numbers
119%
120% NEEDS TESTING
121%
122u_dec_unary_([], _, Sum, Sum).
123u_dec_unary_([D|T], Mult, Sum, R) :-
124	u_to_d(X, D),
125	mul(Mult, X, Num),
127
128	unary_10(M),
129	mul(Mult, M, NewMult),
130
131	u_dec_unary_(T, NewMult, Sum1, R).
132
133% string_unary(String, Unary).
134%
135% Unary is the punary version of String
136%
137string_unary(D, C) :-
138	reverse(D, DR),
139	u_dec_unary_(DR, c(zero), zero, C).
140
141%
142% convert unary numbers to strings
143%
144% NEEDS TESTING
145%
146u_unary_dec(zero, _, []).
147u_unary_dec(c(Z), Mul, [V|T]) :-
148	unary_10(U_10),
149	mul(Mul, U_10, NewMul),
150	div(c(Z), NewMul, LeftOver, R),
151	u_to_d(R, V),
152
153	u_unary_dec(LeftOver, NewMul, T).
154
155% unary_string(Unary, String).
156%
157% String is the pstring version of Unary
158%
159unary_string(U, S) :-
160	u_unary_dec(U, c(zero), R),
161	reverse(R, S)```