Recent

Poll

I know the answer.

false
0 (0%)
unknown
4 (80%)
true
1 (20%)

Total Members Voted: 5

Author Topic: trinary logic with operator overloads  (Read 10587 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 14358
  • Sensorship about opinions does not belong here.
Re: trinary logic with operator overloads
« Reply #15 on: May 08, 2018, 09:15:49 am »
[Why doesn't the following work?
Code: Pascal  [Select][+][-]
  1. program op(input, output, stderr);
  2. type
  3.         enum = (zero, one, two, three = one + two);
  4. begin
  5.         writeLn(one + two); // ideally prints three
  6. end.
Well, this works:
Code: Pascal  [Select][+][-]
  1. type enum = (zero, one, two, three = one + two);
  2. begin
  3.   writeLn(enum(ord(one) + ord(two))); // actually prints three
  4. end.
If I only could do that with NOT.... :(

In this case even this works:
Code: Pascal  [Select][+][-]
  1. type enum = (zero = -5, one = 10, two = 7, three = one + two);
  2. begin
  3.   writeLn(enum(ord(one) + ord(two))); // actually prints three
  4.   writeln(Ord(Three)); // should be 17,right?
  5. end.
Ok, compiler has a note...

I still feel that negation, addition and subtraction should be legal as overloads. Maybe not for enums with assigned values, as the ordinal test shows.
That is a hornet's nest.
« Last Edit: May 08, 2018, 09:31:18 am by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Thaddy

  • Hero Member
  • *****
  • Posts: 14358
  • Sensorship about opinions does not belong here.
Re: trinary logic with operator overloads
« Reply #16 on: July 08, 2018, 09:04:42 am »
@Kays
Florian fixed it. In the latest trunk (39406) this now compiles:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. // Kleene and Priest three value logic
  3. // See https://en.wikipedia.org/wiki/Three-valued_logic
  4. type
  5.   ternary = (F, U, T);
  6.    
  7.   operator and (const a,b:ternary):ternary;inline;
  8.     const lookupAnd:array[ternary,ternary] of ternary =
  9.                     ((F,F,F),(F,U,U),(F,U,T));
  10.   begin
  11.     Result:= LookupAnd[a,b];
  12.   end;
  13.          
  14.   operator or (const a,b:ternary):ternary;inline;
  15.     const lookupOr:array[ternary,ternary] of ternary =
  16.                    ((F,U,T),(U,U,T),(T,T,T));
  17.   begin
  18.     Result := LookUpOr[a,b];
  19.   end;
  20.  
  21.   operator not (const a:ternary):ternary;inline;
  22.     const LookupNot:array[ternary] of ternary =(T,U,F);
  23.   begin
  24.      Result:= LookUpNot[a];
  25.   end;
  26.  
  27.  
  28. begin
  29.   // works as expected
  30.   writeln('AND');write(F and F);write(F and U);
  31.   writeln(F and T);write(U and F);write(U and U);
  32.   writeln(U and T);write(T and F);write(T and U);
  33.   writeln(T and T);
  34.   writeln;
  35.   //works as expected
  36.   writeln('OR');write(F or F);write(F or U);
  37.   writeln(F or T);write(U or F);write(U or U);
  38.   writeln(U or T);write(T or F);write(T or U);
  39.   writeln(T or T);
  40.   writeln;
  41.   // works as expected from rev 39406+
  42.   writeln('NOT');
  43.   writeln(not F);
  44.   writeln(not U);
  45.   writeln(not T);
  46.   writeln;
  47.   // works as expected too
  48.   // Material implication for Kleene logic is defined as not(a) or b
  49.   writeln('IMP -> not(a) or b');
  50.   write(not(T) or T);write(not(U) or T);writeln(not(F) or T);
  51.   write(not(T) or U);write(not(U) or U);writeln(not(F) or U);
  52.   write(not(T) or F);write(not(U) or F);writeln(not(F) or F);    
  53. end.
  54.  
[edit] added test for imp, which is not(a) or b
So here we have it.
« Last Edit: July 08, 2018, 12:36:49 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Thaddy

  • Hero Member
  • *****
  • Posts: 14358
  • Sensorship about opinions does not belong here.
Re: trinary logic with operator overloads
« Reply #17 on: July 08, 2018, 01:52:44 pm »
I also tested a five way and a nine way logic system. Now also works.
Quite impressive that we can do such things and it has really good applicability in electronics and machine learning.
Tnx Florian!! (And Kays for bringing it up!!)
« Last Edit: July 08, 2018, 01:59:54 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Thaddy

  • Hero Member
  • *****
  • Posts: 14358
  • Sensorship about opinions does not belong here.
Re: trinary logic with operator overloads
« Reply #18 on: July 09, 2018, 03:12:30 pm »
I have attached an implementation of a symmetrically balanced 5-way logic for those who are interested.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Thaddy

  • Hero Member
  • *****
  • Posts: 14358
  • Sensorship about opinions does not belong here.
Re: trinary logic with operator overloads
« Reply #19 on: August 24, 2018, 08:19:23 pm »
I found similar code on rosettacode today. Gave me some idea's (this one is imho still neater than what's there.)
I re-invented wheels again  :-X https://rosettacode.org/wiki/Ternary_logic
Strange it didn't show up before in my searches.
This logic is now complete, what's missing can all be solved with these basics: it is a neat set of operators suitable for electronics, science, sql and the likes:
Code: Pascal  [Select][+][-]
  1. program ternarytests;
  2. {$mode objfpc}
  3. {
  4. * Evaluated, added XOR, and tested against other languages after seeing code on rosettacode.
  5. * They used almost all similar code. So I decided to finish it
  6. *
  7.   Currently the equality operator can not be overridden for equal types but
  8.   1. equality is the same as: NOT (x XOR y)
  9.   2. IMP is the same as: (NOT x) OR y
  10.   So these two demonstrate the logic works!
  11.  
  12.   Enjoy,
  13.  
  14.   Thaddy
  15. }
  16. type
  17.   { ternary type }
  18.   trit = (F, U, T);
  19.    
  20.   operator and (const a,b:trit):trit;inline;
  21.     const lookupAnd:array[trit,trit] of trit =
  22.                     ((F,F,F),(F,U,U),(F,U,T));
  23.   begin
  24.     Result:= LookupAnd[a,b];
  25.   end;
  26.          
  27.   operator or (const a,b:trit):trit;inline;
  28.     const lookupOr:array[trit,trit] of trit =
  29.                    ((F,U,T),(U,U,T),(T,T,T));
  30.   begin
  31.     Result := LookUpOr[a,b];
  32.   end;
  33.  
  34.   operator not (const a:trit):trit;inline;
  35.     const LookupNot:array[trit] of trit =(T,U,F);
  36.   begin
  37.      Result:= LookUpNot[a];
  38.   end;
  39.  
  40.   operator xor (const a,b:trit):trit;
  41.     const LookupXor:array[trit,trit] of trit =
  42.     ((F,U,T),(U,U,U),(T,U,F));
  43.   begin
  44.     Result := LookupXor[a,b];
  45.   end;
  46.  
  47. // just tests...
  48. begin
  49.   writeln(' a AND b');
  50.   writeln('__FUT');
  51.   writeln('F|',F and F,F and U,F and T);
  52.   writeln('U|',U and F,U and U,U and T);
  53.   writeln('T|',T and F,T and U,T and T);
  54.   writeln;
  55.  
  56.   writeln(' a OR b');
  57.   writeln('__FUT');
  58.   writeln('F|',F or F,F or U,F or T);
  59.   writeln('U|',U or F,U or U,U or T);
  60.   writeln('T|',T or F,T or U,T or T);
  61.   writeln;
  62.  
  63.   writeln(' NOT a');
  64.   writeln('__FUT');
  65.   writeln('F|',not F);
  66.   writeln('U|',not U);
  67.   writeln('T|',not T);
  68.   writeln;
  69.  
  70.   writeln(' a XOR b');
  71.   writeln('__FUT');
  72.   writeln('F|',F xor F,F xor U,F xor T);
  73.   writeln('U|',U xor F,U xor U,U xor T);
  74.   writeln('T|',T xor F,T xor U,T xor T);
  75.   writeln;
  76.  
  77.   writeln(' NOT (a  XOR b)  -> equality/equivalence');
  78.   writeln('__FUT');
  79.   writeln('F|',not(F xor F),not(F xor U),not(F xor T));
  80.   writeln('U|',not(U xor F),not(U xor U),not(U xor T));
  81.   writeln('T|',not(T xor F),not(T xor U),not(T xor T));
  82.   writeln;
  83.  
  84.   writeln('IMP. a.k.a. IfThen -> not(a) or b');
  85.   writeln('T|',(not T) or T,(not T) or U,(not T) or F);
  86.   writeln('U|',(not U) or T,(not U) or U,(not U) or F);
  87.   writeln('F|',(not F) or T,(not F) or U,(not F) or F);
  88. end.

This is a Kleene and Priest logic as per OP's original question.
I will introduce the XOR operation in my five way logic too and will add a nine way logic.
(The latter two can be used for de-fuzzing fuzzy logic, for which I wrote operators too)

I think it can't be written much simpler than that!

« Last Edit: August 25, 2018, 07:23:03 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Thaddy

  • Hero Member
  • *****
  • Posts: 14358
  • Sensorship about opinions does not belong here.
Re: trinary logic with operator overloads
« Reply #20 on: August 25, 2018, 04:34:08 pm »
Here's the fuzzy part: Zadeh's classic standard fuzzy logic:
Code: Pascal  [Select][+][-]
  1. program zadehlogic;
  2. {$mode objfpc}{$notes off}
  3. { Zadeh's standard fuzzy logic operators
  4.  See:
  5.    https://commons.wikimedia.org/wiki/Fuzzy_operator
  6.  
  7.  Don't let your eyes fool you, these are not integer or boolean
  8.  calculations, but floating point calculations!.
  9.  
  10.  Enjoy,
  11.  
  12.  Thaddy }
  13. type
  14.   { Fuzz is a double in the inclusive range 0..1
  15.     The programmer is responsible for valid input.
  16.     (You can use EnsureRange from the math unit.) }
  17.   Fuzz = type double;  
  18.  
  19. { helpers }  
  20.   function min(const a,b:Fuzz):Fuzz;inline;
  21.   begin    
  22.     if a > b then result := b else result := a;
  23.   end;
  24.  
  25.   function max(const a,b:Fuzz):Fuzz;inline;
  26.   begin    
  27.     if b > a then result := b else result := a;
  28.   end;
  29.  
  30. { the basic logic }
  31.  
  32.   { AND is defined as min(a, b) in standard fuzzy logic }
  33.   operator and (const a,b:Fuzz):Fuzz;inline;
  34.   begin
  35.     Result:=min(a,b);
  36.   end;
  37.  
  38.   { OR is defined as max(a,b) in standard fuzzy logic }
  39.   operator or (const a,b:Fuzz):Fuzz;inline;
  40.   begin
  41.     Result:=max(a, b);
  42.   end;
  43.  
  44.   { NOT is simply the inverse, given a range of 0..1. Comparable to Boolean}
  45.   operator not (const a:Fuzz):Fuzz;inline;
  46.   begin
  47.     result := 1 - a;
  48.   end;
  49.  
  50.   { XOR. See AND how this reflects: the bias to either a or b gets amplified  }
  51.   operator xor (const a,b:Fuzz):Fuzz;inline;
  52.   begin
  53.     result := a + b - 2 * (a and b);
  54.   end;
  55.  
  56.  { not overloaded logic as functions: all can be derived from the above four }
  57.  
  58.   { IMP }
  59.   function imp(const a,b:Fuzz):Fuzz;inline;
  60.   begin
  61.     Result := not (a and not b)
  62.   end;  
  63.  
  64.   { NAND }
  65.   function nand(const a,b:Fuzz):Fuzz;inline;
  66.   begin
  67.     Result := not (a and b);
  68.   end;
  69.  
  70.   { NOR }
  71.   function nor(const a,b:Fuzz):Fuzz;inline;
  72.   begin
  73.     Result := not (a or b);
  74.   end;
  75.  
  76.   { NXR }
  77.   function nxr(const a,b:Fuzz):Fuzz;inline;
  78.   begin
  79.     Result := not (a xor b);
  80.   end;
  81.  
  82.   { NIMP }
  83.   function nimp(const a,b:Fuzz):Fuzz;inline;
  84.   begin
  85.     Result := a and not b;
  86.   end;  
  87.  
  88. begin
  89. end.

« Last Edit: August 25, 2018, 04:47:15 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

 

TinyPortal © 2005-2018