コンピュータは「掛け算は足し算とする」を理解できるか - 檜山正幸のキマイラ飼育記 で解説されている min-plus半環をPowerShellで実現してみようと。
といっても、キモはほとんどC#ですが。
sample.ps1
Add-Type -ReferencedAssemblies Microsoft.CSharp -TypeDefinition @"
using System;
public class MinPlus<T> where T : IComparable<T>
{
private bool isInfinity = false;
private T val;
public MinPlus(T val)
{
this.isInfinity = false;
this.val = val;
}
private MinPlus()
{
this.isInfinity = true;
this.val = default(T);
}
public override string ToString()
{
return (this.isInfinity ? "∞" : this.val.ToString());
}
public static implicit operator MinPlus<T>(T x)
{
return new MinPlus<T>(x);
}
public static MinPlus<T> operator +(MinPlus<T> x, MinPlus<T> y)
{
if (x.isInfinity)
return y;
if (y.isInfinity)
return x;
return (x.val.CompareTo(y.val) < 0 ? x : y);
}
public static MinPlus<T> operator *(MinPlus<T> x, MinPlus<T> y)
{
if (x.isInfinity)
return x;
if (y.isInfinity)
return y;
dynamic xv = x.val;
dynamic yv = y.val;
return xv + yv;
}
public static readonly MinPlus<T> Infinity = new MinPlus<T>();
}
"@ -Language CSharp
実際に計算してみた結果は次の通り。
(sample.ps1を C:\sample\ps に BOMつきUTF-8 で保存しています。)
PS C:\sample\ps> .\sample.ps1
PS C:\sample\ps> (1 -as [MinPlus[double]]) + 1
1
PS C:\sample\ps> 2 + (3 -as [MinPlus[double]])
2
PS C:\sample\ps> 2 * (3 -as [MinPlus[double]])
5
PS C:\sample\ps> 2 * (0 -as [MinPlus[double]])
2
PS C:\sample\ps> 3 + [MinPlus[double]]::Infinity
3
PS C:\sample\ps> 3 * [MinPlus[double]]::Infinity
∞
C#だと+や×といった演算が定義されていることについての型制約が書けないのでその点が残念ではありますね。