Tropical algebra overloading: Difference between revisions
Content added Content deleted
No edit summary |
Thundergnat (talk | contribs) 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> |
||
< |
<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</ |
END</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 84: | Line 84: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<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}} |
||
< |
<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</ |
} [ show ] each</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 261: | Line 261: | ||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
Using preprocessor macros. |
Using preprocessor macros. |
||
< |
<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</ |
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. |
||
< |
<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)) |
||
}</ |
}</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. |
||
< |
<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"</ |
opError op = error $ op ++ " is not defined on a max-plus semiring"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 502: | Line 502: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
< |
<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 |
||
</ |
</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. |
||
< |
<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}."</ |
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. |
||
<!--< |
<!--<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> |
||
<!--</ |
<!--</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}}== |
||
< |
<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) |
||
</ |
</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. |
||
< |
<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") |
||
</ |
</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 |
<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');</ |
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''' doesn't support operator overloading, so functions are needed to be used instead. |
'''REXX''' doesn't support operator overloading, so functions are needed to be used instead. |
||
< |
<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.*/</ |
if isNum(a) | a==negInf() then return a; call notNum a /*show error.*/</syntaxhighlight> |
||
{{out|output|text= when using the internal default input:}} |
{{out|output|text= 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. |
||
< |
<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)}") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 925: | Line 925: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
< |
<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)")</ |
System.print("%(c) ⊗ (%(d) ⊕ %(e)) == %(c) ⊗ %(d) ⊕ %(c) ⊗ %(e) is %(f == g)")</syntaxhighlight> |
||
{{out}} |
{{out}} |