### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Recent

#### Graham1

• New Member
• Posts: 32
« on: September 19, 2021, 06:42:33 am »
I thought I'd learn a bit about operator overloading and decided to use three value booleans (trileans, or trooleans?) as an exercise for this. I've only just started but ran into one thing that I'd like to do but I suspect isn't possible. So far my unit is:

Code: Pascal  [Select][+][-]
1. unit trileans;
2.
4.
5. interface
6.
7. uses SysUtils;
8.
9. const
10.   no      : byte = 0;
11.   yes     : byte = 1;
12.   maybe   : byte = 2;
13.   other   : byte = 2;
14.   unknown : byte = 2;
15.
16. type
17.   Trilean = record
18.     private
19.       val : byte;
20.   end;
21.
22. operator := (b:byte) : trilean;
23. operator := (b:boolean) : trilean;
24. operator = (t:trilean; b:byte) : boolean;
25. operator = (t:trilean; b:boolean) : boolean;
26.
27. function TrilToStr(T:Trilean; UseTrilStrs:Boolean=false):string;
28. function TrilToStr(T:Trilean; const TrueS,FalseS,OtherS:string):string;
29.
30. {------------------------------------------------------------------------}
31.
32. implementation
33.
34. operator := (b:byte) : trilean;
35. begin
36.    result.val:=b;
37. end;
38.
39. operator := (b:boolean) : trilean;
40. begin
41.    if b then result.val:=yes else result.val:=no;
42. end;
43.
44. operator = (t:trilean; b:byte) : boolean;
45. begin
46.    if t.val=b then result:=true else result:=false;
47. end;
48.
49. operator = (t:trilean; b:boolean) : boolean;
50. begin
51.    if b     and (t.val=YES) then result:=true else
52.    if not b and (t.val=NO)  then result:=true else
53.                                  result:=false;
54. end;
55.
56. function TrilToStr(T:Trilean; UseTrilStrs:Boolean=false):string;
57. begin
58.    if UseTrilStrs then begin
59.       if T.val=YES then result:='True' else
60.       if T.val=NO  then result:='False' else
61.                         result:='Other';
62.    end else begin
63.       result:=inttostr(T.val);
64.    end;
65. end;
66.
67. function TrilToStr(T:Trilean; const TrueS,FalseS,OtherS:string):string;
68. begin
69.    if T.val=YES then result:=TrueS else
70.    if T.val=NO  then result:=FalseS else
71.                      result:=OtherS;
72. end;
73.
74. end.

This lets me do things like setting MyTrilean:=true or MyTrilean:=maybe and print out the trilean's values.

But I'd like the trileans to behave just like booleans but with an extra value so my problem is the comparison. I can say:

Code: Pascal  [Select][+][-]
1. if MyTrilean=true then writeln('OK');

but I can't replace this with the neater:

Code: Pascal  [Select][+][-]
1. if MyTrilean then writeln('OK');

The comparison operator requires two parameters and I can't think of any other way to do this. Is there a clever way to provide a function that will allow an immediate evaluation of a record based on whatever rule I choose (in this case if T.val=1)?

As I said, I suspect the answer is no but thought it would be educational to ask!

Also, since this is just a learning exercise is this the method you would use in implementing these or is there something better? I thought of using a class rather than a record but they don't seem to allow operator overloads.

Thanks.

« Last Edit: September 20, 2021, 01:08:24 am by Graham1 »
Windows 10 Home 64-bit
Lazarus 2.0.12 / FPC 3.2.0

#### ASerge

• Hero Member
• Posts: 1887
« Reply #1 on: September 19, 2021, 09:03:08 am »
but I can't replace this with the neater:
Code: Pascal  [Select][+][-]
1. if MyTrilean then writeln('OK');
Define
Code: Pascal  [Select][+][-]
1. operator := (t: Trilean): Boolean;

#### Bart

• Hero Member
• Posts: 4511
« Reply #2 on: September 19, 2021, 02:44:23 pm »
Why do maybe, other and unknown have the same value?
Why do you define them as "writeable constants", is the user allowed to change no to 1, and yes to 0?

Bart

• Hero Member
• Posts: 10991
« Reply #3 on: September 19, 2021, 02:48:38 pm »
« Last Edit: September 19, 2021, 03:10:36 pm by Thaddy »
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

• Hero Member
• Posts: 10991
« Reply #4 on: September 19, 2021, 03:13:33 pm »
Why do maybe, other and unknown have the same value?
Why do you define them as "writeable constants", is the user allowed to change no to 1, and yes to 0?

Bart

Because ithey all express uncertainty. They are equivent names but  part of a three way system.
See https://en.wikipedia.org/wiki/Three-valued_logic

(btw, my older one is a  more complete verion of Kleene and Priest)
« Last Edit: September 19, 2021, 03:15:56 pm by Thaddy »
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

#### Graham1

• New Member
• Posts: 32
« Reply #5 on: September 20, 2021, 01:07:59 am »
Define
Code: Pascal  [Select][+][-]
1. operator := (t: Trilean): Boolean;

Of course! It's quite obvious really - once somebody shows the answer!! Thank you so much, that fixed it and also taught me that assignments are useful not just in setting the values but also in accessing them.

Why do maybe, other and unknown have the same value?
Why do you define them as "writeable constants", is the user allowed to change no to 1, and yes to 0?

As Thaddy says, it's because a trilean has three values. Normally I would use an enumerated list for this but then I would be stuck with the names I chose at the design of this unit. But just because something has three values doesn't mean the third is always "unknown":

Have I won the lottery: Yes, No, I'll find out tonight!
What shape is this: Square, Circle, Something else
The cat in the box is alive: True, False, Both

So I used constants as they are easily added to without changing the actual values used (which are hidden as Val is private). At the same time I also wanted to be able to use the trileans like real booleans to access the true/false (yes/no) values, which is why I wanted ASerge's answer.

Because ithey all express uncertainty. They are equivent names but  part of a three way system.
See https://en.wikipedia.org/wiki/Three-valued_logic

(btw, my older one is a  more complete verion of Kleene and Priest)

I suspected I was reinventing the wheel, but as I mentioned this was an excuse to learn about overrides. I didn't realise trileans/trinaries/... had such an interesting history and so much theory though! If I'd read all that first I might never have started!!

Windows 10 Home 64-bit
Lazarus 2.0.12 / FPC 3.2.0

#### Graham1

• New Member
• Posts: 32
« Reply #6 on: September 22, 2021, 01:39:42 am »
I thought I might as well post my 'finished' version:

Code: Pascal  [Select][+][-]
1. unit trileans;
2.
4.
5. interface
6.
7. uses SysUtils;
8.
9. const
10.   no      : byte = 0;
11.   yes     : byte = 1;
12.   other   : byte = 2;
13.   maybe   : byte = 2;
14.   unknown : byte = 2;
15.
16. type
17.   Trilean = record
18.     private
19.       val : byte;
20.   end;
21.
22. operator := (b:byte) : trilean;
23. operator := (b:boolean) : trilean;
24. operator := (t:trilean) : boolean;
25. operator := (t:trilean) : string;
26.
27. operator = (t:trilean; b:byte) : boolean;
28. operator = (t:trilean; b:boolean) : boolean;
29.
30. operator + (t:trilean; s:string) : string;
31. operator + (s:string; t:trilean) : string;
32.
33. operator not (t:trilean) : trilean;
34. operator and (t1,t2:trilean) : trilean;
35. operator or  (t1,t2:trilean) : trilean;
36. operator xor (t1,t2:trilean) : trilean;
37.
38. operator inc (t:trilean) : trilean;
39. operator dec (t:trilean) : trilean;
40.
41.
42. function TrilToStr(T:Trilean; UseTrilStrs:Boolean=false):string;
43. function TrilToStr(T:Trilean; const TrueS,FalseS,OtherS:string):string;
44.
45. {------------------------------------------------------------------------}
46.
47. implementation
48.
49. operator := (b:byte) : trilean;
50. begin
51.    if (b=YES) or (b=NO) or (b=OTHER) then result.val:=b;
52. end;
53.
54. operator := (b:boolean) : trilean;
55. begin
56.    if b then result.val:=YES else result.val:=NO;
57. end;
58.
59. operator := (t:trilean) : boolean;
60. begin
61.    if t.val=YES then result:=true else result:=false;
62. end;
63.
64. operator := (t:trilean) : string;
65. begin
66.    if t.val=YES then result:='TRUE' else
67.    if t.val=NO  then result:='FALSE' else
68.                      result:='OTHER';
69. end;
70.
71. operator = (t:trilean; b:byte) : boolean;
72. begin
73.    if t.val=b then result:=true else result:=false;
74. end;
75.
76. operator = (t:trilean; b:boolean) : boolean;
77. begin
78.    if b     and (t.val=YES) then result:=true else
79.    if not b and (t.val=NO)  then result:=true else
80.                                  result:=false;
81. end;
82.
83. operator + (t:trilean; s:string) : string;
84. begin
85.    if t.val=YES then result:='TRUE'+s else
86.    if t.val=NO  then result:='FALSE'+s else
87.                      result:='OTHER'+s;
88. end;
89.
90. operator + (s:string; t:trilean) : string;
91. begin
92.    if t.val=YES then result:=s+'TRUE' else
93.    if t.val=NO  then result:=s+'FALSE' else
94.                      result:=s+'OTHER';
95. end;
96.
97. operator not (t:trilean) : trilean;
98. begin
99.    if T.val=YES then result.val:=NO  else
100.    if T.val=NO  then result.val:=YES else
101.                      result.val:=OTHER;
102. end;
103.
104. operator and (t1,t2:trilean) : trilean;
105. begin
106.    if (t1.val=NO) or (t2.val=NO)    then result.val:=NO else
107.    if (t1.val=YES) and (t2.val=YES) then result.val:=YES else
108.                                          result.val:=OTHER;
109. end;
110.
111. operator or (t1,t2:trilean) : trilean;
112. begin
113.    if (t1.val=YES) or (t2.val=YES) then result.val:=YES else
114.    if (t1.val=NO) and (t2.val=NO)  then result.val:=NO else
115.                                         result.val:=OTHER;
116. end;
117.
118. operator xor (t1,t2:trilean) : trilean;
119. begin
120.    if (t1.val=YES) and (t2.val=NO)  then result.val:=YES else
121.    if (t1.val=NO)  and (t2.val=YES) then result.val:=YES else
122.    if (t1.val=YES) and (t2.val=YES) then result.val:=NO else
123.    if (t1.val=NO)  and (t2.val=NO)  then result.val:=NO else
124.                                          result.val:=OTHER;
125. end;
126.
127. operator inc (t:trilean) : trilean;
128. begin
129.    if t.val=NO    then result.val:=OTHER else
130.    if t.val=OTHER then result.val:=YES   else
131.                        result.val:=t.val;
132. end;
133.
134. operator dec (t:trilean) : trilean;
135. begin
136.    if t.val=YES   then result.val:=OTHER else
137.    if t.val=OTHER then result.val:=NO    else
138.                        result.val:=t.val;
139. end;
140.
141.
142. function TrilToStr(T:Trilean; UseTrilStrs:Boolean=false):string;
143. begin
144.    if UseTrilStrs then begin
145.       if T.val=YES then result:='True' else
146.       if T.val=NO  then result:='False' else
147.                         result:='Other';
148.    end else begin
149.       result:=inttostr(T.val);
150.    end;
151. end;
152.
153. function TrilToStr(T:Trilean; const TrueS,FalseS,OtherS:string):string;
154. begin
155.    if T.val=YES then result:=TrueS else
156.    if T.val=NO  then result:=FalseS else
157.                      result:=OtherS;
158. end;
159.
160.
161. end.

This can be used like booleans but with an extra value, for example:

Code: Pascal  [Select][+][-]
1. program TrileanUse;
2.
3. {\$mode objfpc}{\$H+}
4.
5. uses trileans;
6.
7. var
8.   tr1, tr2 : trilean;
9.   i, j     : byte;
10.   ab       : array[1..3] of byte;
11.
12. begin
13.
14.   tr1:=maybe;
15.   write('tr1 set to MAYBE. tr1 is now: ');
16.   writeln(TriltoStr(tr1,true));
17.
18.   tr2:=tr1;
19.   writeln('tr1 copied to tr2');
20.
21.   tr1:=true;
22.   write('tr1 set to TRUE. tr1 is now: ');
23.   writeln(TriltoStr(tr1,true));
24.
25.   write('tr2 is still: ');
26.   writeln(TriltoStr(tr2,true));
27.
28.   if tr1 then writeln('Is tr1 true? Yes') else writeln('Is tr1 true? No');
29.   if not tr1 then writeln('Is tr1 false? Yes') else writeln('Is tr1 false? No');
30.   if tr1 or not tr1 then writeln('tr1 is Known') else writeln('tr1 is Unknown');
31.
32.   tr1:=other;
33.   writeln('tr1 set to OTHER');
34.   if tr1 then writeln('Is tr1 true? Yes') else writeln('Is tr1 true? No');
35.   if not tr1 then writeln('Is tr1 false? Yes') else writeln('Is tr1 false? No');
36.   if tr1 or not tr1 then writeln('tr1 is Known') else writeln('tr1 is Unknown');
37.   writeln;
38.
39.   ab[1]:=NO;
40.   ab[2]:=OTHER;
41.   ab[3]:=YES;
42.
43.   writeln(' NOT      AND F O T     OR  F O T     XOR F O T      INC       DEC');
44.
45.   for i in ab do begin
46.     tr1:=i;
47.     write(' '+TrilToStr(tr1,'T','F','O'));
48.
49.     tr2:=not tr1;
50.     write('  '+TrilToStr(tr2,'t','f','o'));
51.
52.     write('      '+TrilToStr(tr1,'T','F','O')+' ');
53.     for j in ab do begin
54.        tr2:=j;
55.        write(' '+TrilToStr(tr1 and tr2,'t','f','o'));
56.     end;
57.
58.     write('      '+TrilToStr(tr1,'T','F','O')+' ');
59.     for j in ab do begin
60.        tr2:=j;
61.        write(' '+TrilToStr(tr1 or tr2,'t','f','o'));
62.     end;
63.
64.     write('      '+TrilToStr(tr1,'T','F','O')+' ');
65.     for j in ab do begin
66.        tr2:=j;
67.        write(' '+TrilToStr(tr1 xor tr2,'t','f','o'));
68.     end;
69.
70.     write('      '+TrilToStr(tr1,'T','F','O')+' ');
71.     tr2:=tr1;
72.     inc(tr2);
73.     write(' '+TrilToStr(tr2,'t','f','o'));
74.
75.     write('      '+TrilToStr(tr1,'T','F','O')+' ');
76.     tr2:=tr1;
77.     dec(tr2);
78.     write(' '+TrilToStr(tr2,'t','f','o'));
79.
80.     writeln;
81.   end;
82.
83.   writeln;
84.   writeln('Press enter to quit');
86.
87. end.

This outputs:

Code: Text  [Select][+][-]
1. tr1 set to MAYBE. tr1 is now: Other
2. tr1 copied to tr2
3. tr1 set to TRUE. tr1 is now: True
4. tr2 is still: Other
5. Is tr1 true? Yes
6. Is tr1 false? No
7. tr1 is Known
8. tr1 set to OTHER
9. Is tr1 true? No
10. Is tr1 false? No
11. tr1 is Unknown
12.
13.  NOT      AND F O T     OR  F O T     XOR F O T      INC       DEC
14.  F  t      F  f f f      F  f o t      F  f o t      F  o      F  f
15.  O  o      O  f o o      O  o o t      O  o o o      O  t      O  f
16.  T  f      T  f o t      T  t t t      T  t o f      T  t      T  o

Thank you everyone for your help.

Windows 10 Home 64-bit
Lazarus 2.0.12 / FPC 3.2.0