1:- module(punary, [
2 unary/1,
3 pow/3,
4 string_unary/2,
5 unary_string/2,
6 add/3,
7 mul/3,
8 div/4
9]). 10
11:- use_module(purity). 12
13:- multifile(purity:pcompare/4). 14:- multifile(purity:ptype/2). 15
16purity:ptype(zero, punary).
17purity:ptype(c(_), punary).
18
19purity:pcompare(punary, A, B, C) :-
20 unary_compare(A, B, C).
21
23unary_compare(zero, U2, C) :- unary_compare_z(U2, C).
24unary_compare(c(Z), U2, C) :- unary_compare_c(U2, c(Z), C).
25
26unary_compare_z(zero, =).
27unary_compare_z(c(_), <).
28
29unary_compare_c(zero, _, >).
30unary_compare_c(c(Z2), c(Z1), C) :-
31 unary_compare(Z1, Z2, C).
32
34unary(zero).
35unary(c(Z)) :- unary(Z).
36
38add(zero, Z, Z).
39add(c(X), Y, c(Z)) :-
40 add(X, Y, Z).
41
43mul(zero, _, zero).
44mul(c(X), Y, R) :-
45 add(Y, S, R),
46 mul(X, Y, S).
47
49div(S, D, Q, R) :-
50 unary_compare(zero, R, C),
51 unary_div(C, S, D, Q, R).
52
53unary_div(=, S, D, Q, zero) :-
54 mul(D, Q, S).
55unary_div(>, S, D, Q, zero) :-
56 mul(D, Q, S).
57unary_div(<, S, D, Q, R) :-
58 unary_compare(R, D, <),
59 add(Is, R, S),
60 mul(D, Q, Is).
61
63pow(zero, zero, zero).
64pow(N, c(zero), N).
65pow(N, c(c(Z)), R) :-
66 mul(N, R1, R),
67 pow(N, c(Z), R1).
68
72d_to_u(U, N) :-
73 d_to_u_(['0','1','2','3','4','5','6','7','8','9'], N, U).
74
75d_to_u_([A|T], N, U) :-
76 pcompare(A, N, C),
77 d_to_u_(C, N, T, U).
78
79d_to_u_(=, _, _, zero).
80d_to_u_(>, N, T, c(Z)) :-
81 d_to_u_(T, N, Z).
82d_to_u_(<, N, T, c(Z)) :-
83 d_to_u_(T, N, Z).
84
88u_to_d(U, D) :-
89 u_to_d_(U, ['0','1','2','3','4','5','6','7','8','9'], D).
90
91u_to_d_(zero, [D|_], D).
92u_to_d_(c(Z), [_|T], D) :-
93 u_to_d_(Z, T, D).
94
96unary_10( c(c(c(c(c(c(c(c(c(c(zero)))))))))) ).
97
99string_unary(D, C) :-
100 reverse(D, DR),
101 u_dec_unary_(DR, c(zero), zero, C).
102
103u_dec_unary_([], _, Sum, Sum).
104u_dec_unary_([D|T], Mult, Sum, R) :-
105 u_to_d(X, D),
106 mul(Mult, X, Num),
107 add(Sum, Num, Sum1),
108
109 unary_10(M),
110 mul(Mult, M, NewMult),
111
112 u_dec_unary_(T, NewMult, Sum1, R).
113
114
116unary_string(U, S) :-
117 u_unary_dec(U, c(zero), R),
118 reverse(R, S).
119
120u_unary_dec(zero, _, []).
121u_unary_dec(c(Z), Mul, [V|T]) :-
122 unary_10(U_10),
123 mul(Mul, U_10, NewMul),
124 div(c(Z), NewMul, LeftOver, R),
125 u_to_d(R, V),
126 u_unary_dec(LeftOver, NewMul, T)