Tropical algebra overloading: Difference between revisions

Content added Content deleted
No edit summary
m (syntax highlighting fixup automation)
Line 34: Line 34:
Algol 68 allows operator overloading and even re-defining the built in operators (though the latter is probably frowned on).<br>
Algol 68 allows operator overloading and even re-defining the built in operators (though the latter is probably frowned on).<br>
Either existing symbols or new symbols or "bold" (normally uppercase) words can be used. Unfortunately, (X) and (+) can't be used as operator symbols, so X is used for (X), + for (+) and ^ for exponentiaion. The standard + and ^ operators are redefined.<br>
Either existing symbols or new symbols or "bold" (normally uppercase) words can be used. Unfortunately, (X) and (+) can't be used as operator symbols, so X is used for (X), + for (+) and ^ for exponentiaion. The standard + and ^ operators are redefined.<br>
<lang algol68>BEGIN # tropical algebra operator overloading #
<syntaxhighlight lang="algol68">BEGIN # tropical algebra operator overloading #


REAL minus inf = - max real;
REAL minus inf = - max real;
Line 71: Line 71:
check( 5 X ( 8 + 7 ), "5 (X) ( 8 (+) 7 ) = 5 (X) 8 (+) 5 (X) 7", 5 X 8 + 5 X 7 )
check( 5 X ( 8 + 7 ), "5 (X) ( 8 (+) 7 ) = 5 (X) 8 (+) 5 (X) 7", 5 X 8 + 5 X 7 )
END
END
END</lang>
END</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 84: Line 84:


=={{header|C++}}==
=={{header|C++}}==
<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <optional>
#include <optional>


Line 207: Line 207:
}
}


</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 223: Line 223:
=={{header|Factor}}==
=={{header|Factor}}==
{{works with|Factor|0.99 2021-06-02}}
{{works with|Factor|0.99 2021-06-02}}
<lang factor>USING: io kernel math math.order present prettyprint sequences
<syntaxhighlight lang="factor">USING: io kernel math math.order present prettyprint sequences
typed ;
typed ;


Line 244: Line 244:
[ 5 8 ⊗ 5 7 ⊗ ⊕ ]
[ 5 8 ⊗ 5 7 ⊗ ⊕ ]
[ 8 7 ⊕ 5 ⊗ 5 8 ⊗ 5 7 ⊗ ⊕ = ]
[ 8 7 ⊕ 5 ⊗ 5 8 ⊗ 5 7 ⊗ ⊕ = ]
} [ show ] each</lang>
} [ show ] each</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 261: Line 261:
=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
Using preprocessor macros.
Using preprocessor macros.
<lang freebasic>#define Inf 9223372036854775807
<syntaxhighlight lang="freebasic">#define Inf 9223372036854775807
#define tropicalAdd(x,y) iif((x > y), (x), (y))
#define tropicalAdd(x,y) iif((x > y), (x), (y))
#define tropicalMul(x,y) (x + y)
#define tropicalMul(x,y) (x + y)
Line 276: Line 276:
Print "tropicalMul(5,tropicalAdd(8,7)) = tropicalAdd(tropicalMul(5,8),tropicalMul(5,7)) = "; _
Print "tropicalMul(5,tropicalAdd(8,7)) = tropicalAdd(tropicalMul(5,8),tropicalMul(5,7)) = "; _
CBool(tropicalMul(5,tropicalAdd(8,7)) = tropicalAdd(tropicalMul(5,8),tropicalMul(5,7)))
CBool(tropicalMul(5,tropicalAdd(8,7)) = tropicalAdd(tropicalMul(5,8),tropicalMul(5,7)))
Sleep</lang>
Sleep</syntaxhighlight>




Line 282: Line 282:
{{trans|Wren}}
{{trans|Wren}}
Go doesn't support operator overloading so we need to use functions instead.
Go doesn't support operator overloading so we need to use functions instead.
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 375: Line 375:
fmt.Printf("%s ⊗ %s ⊕ %s ⊗ %s = %s\n", c, d, c, e, g)
fmt.Printf("%s ⊗ %s ⊕ %s ⊗ %s = %s\n", c, d, c, e, g)
fmt.Printf("%s ⊗ (%s ⊕ %s) == %s ⊗ %s ⊕ %s ⊗ %s is %t\n", c, d, e, c, d, c, e, f.eq(g))
fmt.Printf("%s ⊗ (%s ⊕ %s) == %s ⊗ %s ⊕ %s ⊗ %s is %t\n", c, d, e, c, d, c, e, f.eq(g))
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 392: Line 392:
=={{header|Haskell}}==
=={{header|Haskell}}==
Looks like the Haskell pretty printer thinks the single quote in 'Maxima begins a character constant.
Looks like the Haskell pretty printer thinks the single quote in 'Maxima begins a character constant.
<lang haskell>{-# LANGUAGE DataKinds, DerivingVia, FlexibleInstances, StandaloneDeriving #-}
<syntaxhighlight lang="haskell">{-# LANGUAGE DataKinds, DerivingVia, FlexibleInstances, StandaloneDeriving #-}


import Prelude hiding ((^))
import Prelude hiding ((^))
Line 487: Line 487:


opError :: String -> a
opError :: String -> a
opError op = error $ op ++ " is not defined on a max-plus semiring"</lang>
opError op = error $ op ++ " is not defined on a max-plus semiring"</syntaxhighlight>


{{out}}
{{out}}
Line 502: Line 502:


=={{header|Julia}}==
=={{header|Julia}}==
<lang julia>⊕(x, y) = max(x, y)
<syntaxhighlight lang="julia">⊕(x, y) = max(x, y)
⊗(x, y) = x + y
⊗(x, y) = x + y
↑(x, y) = (@assert round(y) == y && y > 0; x * y)
↑(x, y) = (@assert round(y) == y && y > 0; x * y)
Line 515: Line 515:
@show 5 ⊗ 8 ⊕ 5 ⊗ 7
@show 5 ⊗ 8 ⊕ 5 ⊗ 7
@show 5 ⊗ (8 ⊕ 7) == 5 ⊗ 8 ⊕ 5 ⊗ 7
@show 5 ⊗ (8 ⊕ 7) == 5 ⊗ 8 ⊕ 5 ⊗ 7
</lang>{{out}}
</syntaxhighlight>{{out}}
<pre>
<pre>
2 ⊗ -2 = 0
2 ⊗ -2 = 0
Line 533: Line 533:
We also defined the -Inf value as a constant, MinusInfinity.
We also defined the -Inf value as a constant, MinusInfinity.


<lang Nim>import strformat
<syntaxhighlight lang="nim">import strformat


type MaxTropical = distinct float
type MaxTropical = distinct float
Line 577: Line 577:
echo &"5 ⊗ (8 ⊕ 7) = {x}"
echo &"5 ⊗ (8 ⊕ 7) = {x}"
echo &"5 ⊗ 8 ⊕ 5 ⊗ 7 = {y}"
echo &"5 ⊗ 8 ⊕ 5 ⊗ 7 = {y}"
echo &"So 5 ⊗ (8 ⊕ 7) equals 5 ⊗ 8 ⊕ 5 ⊗ 7 is {x == y}."</lang>
echo &"So 5 ⊗ (8 ⊕ 7) equals 5 ⊗ 8 ⊕ 5 ⊗ 7 is {x == y}."</syntaxhighlight>


{{out}}
{{out}}
Line 593: Line 593:
=={{header|Phix}}==
=={{header|Phix}}==
Phix does not support operator overloading. I trust max is self-evident, sq_add and sq_mul are existing wrappers to the + and * operators, admittedly with extra (sequence) functionality we don't really need here, but they'll do just fine.
Phix does not support operator overloading. I trust max is self-evident, sq_add and sq_mul are existing wrappers to the + and * operators, admittedly with extra (sequence) functionality we don't really need here, but they'll do just fine.
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.1"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (minor/backportable bugfix rqd to handling of -inf in printf[1])</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.1"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (minor/backportable bugfix rqd to handling of -inf in printf[1])</span>
Line 619: Line 619:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tropicalMul(5,tropicalAdd(8,7)) == tropicalAdd(tropicalMul(5,8),tropicalMul(5,7)) = %t\n"</span><span style="color: #0000FF;">,</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tropicalMul(5,tropicalAdd(8,7)) == tropicalAdd(tropicalMul(5,8),tropicalMul(5,7)) = %t\n"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">tropicalMul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tropicalAdd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">))</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">tropicalAdd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tropicalMul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">),</span><span style="color: #000000;">tropicalMul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">))})</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">tropicalMul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tropicalAdd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">))</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">tropicalAdd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tropicalMul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">),</span><span style="color: #000000;">tropicalMul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">))})</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
<small>[1]This task exposed a couple of "and o!=inf" that needed to become "and o!=inf and o!=-inf" in builtins\VM\pprintfN.e - thanks!</small>
<small>[1]This task exposed a couple of "and o!=inf" that needed to become "and o!=inf and o!=-inf" in builtins\VM\pprintfN.e - thanks!</small>
{{out}}
{{out}}
Line 635: Line 635:


=={{header|Python}}==
=={{header|Python}}==
<lang python>from numpy import Inf
<syntaxhighlight lang="python">from numpy import Inf


class MaxTropical:
class MaxTropical:
Line 687: Line 687:
print("5 * (8 + 7) == 5 * 8 + 5 * 7", j * (l + k) == j * l + j * k)
print("5 * (8 + 7) == 5 * 8 + 5 * 7", j * (l + k) == j * l + j * k)


</lang>{{out}}
</syntaxhighlight>{{out}}
<pre>
<pre>
2 * -2 == 0
2 * -2 == 0
Line 702: Line 702:
=={{header|R}}==
=={{header|R}}==
R's overloaded operators, denoted by %_%, have different precedence order than + and *, so parentheses are needed for the distributive example.
R's overloaded operators, denoted by %_%, have different precedence order than + and *, so parentheses are needed for the distributive example.
<lang r>"%+%"<- function(x, y) max(x, y)
<syntaxhighlight lang="r">"%+%"<- function(x, y) max(x, y)


"%*%" <- function(x, y) x + y
"%*%" <- function(x, y) x + y
Line 720: Line 720:
cat("5 %*% 8 %+% 5 %*% 7 ==", (5 %*% 8) %+% (5 %*% 7), "\n")
cat("5 %*% 8 %+% 5 %*% 7 ==", (5 %*% 8) %+% (5 %*% 7), "\n")
cat("5 %*% 8 %+% 5 %*% 7 == 5 %*% (8 %+% 7))", 5 %*% (8 %+% 7) == (5 %*% 8) %+% (5 %*% 7), "\n")
cat("5 %*% 8 %+% 5 %*% 7 == 5 %*% (8 %+% 7))", 5 %*% (8 %+% 7) == (5 %*% 8) %+% (5 %*% 7), "\n")
</lang>{{out}}
</syntaxhighlight>{{out}}
<pre>
<pre>
2 %*% -2 == 0
2 %*% -2 == 0
Line 736: Line 736:
No need to overload, define our own operators with whatever precedence level we want. Here we're setting precedence equivalent to existing operators.
No need to overload, define our own operators with whatever precedence level we want. Here we're setting precedence equivalent to existing operators.


<lang perl6>sub infix:<⊕> (Real $a, Real $b) is equiv(&[+]) { $a max $b }
<syntaxhighlight lang="raku" line>sub infix:<⊕> (Real $a, Real $b) is equiv(&[+]) { $a max $b }
sub infix:<⊗> (Real $a, Real $b) is equiv(&[×]) { $a + $b }
sub infix:<⊗> (Real $a, Real $b) is equiv(&[×]) { $a + $b }
sub infix:<↑> (Real $a, Int $b where * ≥ 0) is equiv(&[**]) { [⊗] $a xx $b }
sub infix:<↑> (Real $a, Int $b where * ≥ 0) is equiv(&[**]) { [⊗] $a xx $b }
Line 749: Line 749:
is-deeply( 5 ↑ 7, 35, '5 ↑ 7 == 35' );
is-deeply( 5 ↑ 7, 35, '5 ↑ 7 == 35' );
is-deeply( 5 ⊗ (8 ⊕ 7), 5 ⊗ 8 ⊕ 5 ⊗ 7, '5 ⊗ (8 ⊕ 7) == 5 ⊗ 8 ⊕ 5 ⊗ 7');
is-deeply( 5 ⊗ (8 ⊕ 7), 5 ⊗ 8 ⊕ 5 ⊗ 7, '5 ⊗ (8 ⊕ 7) == 5 ⊗ 8 ⊕ 5 ⊗ 7');
is-deeply( 5 ↑ 7 ⊕ 6 ↑ 6, 36, '5 ↑ 7 ⊕ 6 ↑ 6 == 36');</lang>
is-deeply( 5 ↑ 7 ⊕ 6 ↑ 6, 36, '5 ↑ 7 ⊕ 6 ↑ 6 == 36');</syntaxhighlight>
{{out}}
{{out}}
<pre>ok 1 - 2 ⊗ -2 == 0
<pre>ok 1 - 2 ⊗ -2 == 0
Line 762: Line 762:
=={{header|REXX}}==
=={{header|REXX}}==
'''REXX''' &nbsp; doesn't support operator overloading, &nbsp; so functions are needed to be used instead.
'''REXX''' &nbsp; doesn't support operator overloading, &nbsp; so functions are needed to be used instead.
<lang rexx>/*REXX pgm demonstrates max tropical semi─ring with overloading: topAdd, topMul, topExp.*/
<syntaxhighlight lang="rexx">/*REXX pgm demonstrates max tropical semi─ring with overloading: topAdd, topMul, topExp.*/
call negInf; @x= '(x)'; @a= '(+)'; @h= '(^)'; @e= 'expression'; @c= 'comparison'
call negInf; @x= '(x)'; @a= '(+)'; @h= '(^)'; @e= 'expression'; @c= 'comparison'
numeric digits 1000 /*be able to handle negative infinity. */
numeric digits 1000 /*be able to handle negative infinity. */
Line 800: Line 800:
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
isRing: procedure; parse arg a,b; if ABnInf() then return negInf /*return -∞ */
isRing: procedure; parse arg a,b; if ABnInf() then return negInf /*return -∞ */
if isNum(a) | a==negInf() then return a; call notNum a /*show error.*/</lang>
if isNum(a) | a==negInf() then return a; call notNum a /*show error.*/</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default input:}}
{{out|output|text=&nbsp; when using the internal default input:}}
<pre>
<pre>
Line 818: Line 818:
{{trans|Go}}
{{trans|Go}}
Vlang doesn't support operator overloading so we need to use functions instead.
Vlang doesn't support operator overloading so we need to use functions instead.
<lang vlang>import math
<syntaxhighlight lang="vlang">import math
const (
const (
Line 909: Line 909:
println("$c ⊗ $d ⊕ $c ⊗ $e = $g")
println("$c ⊗ $d ⊕ $c ⊗ $e = $g")
println("$c ⊗ ($d ⊕ $e) == $c ⊗ $d ⊕ $c ⊗ $e is ${f.eq(g)}")
println("$c ⊗ ($d ⊕ $e) == $c ⊗ $d ⊕ $c ⊗ $e is ${f.eq(g)}")
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 925: Line 925:


=={{header|Wren}}==
=={{header|Wren}}==
<lang ecmascript>var MinusInf = -1/0
<syntaxhighlight lang="ecmascript">var MinusInf = -1/0


class MaxTropical {
class MaxTropical {
Line 998: Line 998:
System.print("%(c) ⊗ (%(d) ⊕ %(e)) = %(f)")
System.print("%(c) ⊗ (%(d) ⊕ %(e)) = %(f)")
System.print("%(c) ⊗ %(d) ⊕ %(c) ⊗ %(e) = %(g)")
System.print("%(c) ⊗ %(d) ⊕ %(c) ⊗ %(e) = %(g)")
System.print("%(c) ⊗ (%(d) ⊕ %(e)) == %(c) ⊗ %(d) ⊕ %(c) ⊗ %(e) is %(f == g)")</lang>
System.print("%(c) ⊗ (%(d) ⊕ %(e)) == %(c) ⊗ %(d) ⊕ %(c) ⊗ %(e) is %(f == g)")</syntaxhighlight>


{{out}}
{{out}}