fork download
  1. import std.stdio
  2. , std.typecons
  3. , std.traits
  4. , std.algorithm
  5. , std.range
  6. , std.container
  7. , conv = std.conv
  8. , std.format;
  9.  
  10. void main() {
  11. with(Reals)
  12. (mul(add(one, one).add(one).add(one), one.add(one).add(one)).mul(inv(one.add(one).add(one))).mul(inv(one.add(zero))).sub(one)).toString.writeln();
  13.  
  14. with(Complex)
  15. toString(add(one, one)).writeln();
  16.  
  17. with(Quaternion)
  18. toString(add(xs!(one, zero).mul.sub(one), one.add(one).mul(one.add(one)))).writeln();
  19. }
  20.  
  21. alias xs(args...) = args;
  22. alias ids(args...) = args;
  23.  
  24. struct DivAlgebra(K) {
  25. static:
  26. K conj(K);
  27. K zero();
  28. K one();
  29. bool isZero(K);
  30. K add(K, K);
  31. K sub(K, K);
  32. K mul(K, K);
  33. K inv(K);
  34. string toString(K);
  35. }
  36.  
  37. bool sigMatch(alias M, A)() {
  38. enum memsM = __traits(allMembers, M);
  39. foreach(m; memsM) {
  40. if (is(typeof(__traits(getMember, m, M)) : typeof(__traits(getMember, m, A))))
  41. return false;
  42. }
  43. return true;
  44. }
  45.  
  46. /// "sig" or "prototype"
  47. enum bool isDivAlgebra(alias mod)
  48. = () {
  49. alias K = mod.kind;
  50. return
  51. is(K)
  52. && sigMatch!(mod, DivAlgebra!K);
  53. }()
  54. ;
  55.  
  56.  
  57. template BareReals() {
  58. /**/
  59. template sig(Testant) {
  60. enum bool sig = isDivAlgebra!Testant;
  61. }/**/
  62.  
  63.  
  64. public:
  65. alias kind = float;
  66.  
  67. pure {
  68. enum conj = (float x) => x;
  69.  
  70. @property {
  71. float zero() { return 0.0f; }
  72.  
  73. float one() { return 1.0f; }
  74. }
  75.  
  76. enum {
  77. isZero = (float x) => x == 0.0f,
  78.  
  79. add = (float x, float y) => x + y,
  80.  
  81. sub = (float x, float y) => x - y,
  82.  
  83. mul = (float x, float y) => x * y,
  84.  
  85. inv = (float x) => 1.0f / x,
  86. }
  87. }
  88.  
  89. enum toString = (float x) => std.format.format("%g", x);
  90. }
  91.  
  92.  
  93. static if(isDivAlgebra!(BareReals!())) {
  94. alias BareReals!() Reals;
  95. }
  96.  
  97. /// functor "G"
  98. template G(alias Alg)
  99. if(isDivAlgebra!Alg) {
  100.  
  101. public:
  102.  
  103. alias A = Alg;
  104.  
  105. alias kind = Tuple!(A.kind, "r", A.kind, "i");
  106.  
  107. //static:
  108. pure {
  109. enum conj = (kind x) => kind(A.conj(x.r), A.sub(A.zero(), x.i));
  110.  
  111. auto zero() @property { return kind(A.zero, A.zero); }
  112.  
  113. auto one() @property { return kind(A.one, A.zero); }
  114.  
  115.  
  116. enum {
  117. isZero = (kind x) => A.isZero(x.r) && A.isZero(x.i),
  118.  
  119. add = (kind x, kind y) => kind( A.add(x.r, y.r), A.add(x.i, y.i) ),
  120. sub = (kind x, kind y) => kind( A.sub(x.r, y.r), A.sub(x.i, y.i) ),
  121.  
  122. mul = (kind x, kind y) {
  123. return kind(
  124. A.sub( A.mul( x.r, y.r ), A.mul( A.conj(x.i), y.i ) )
  125. , A.add( A.mul(x.r, y.i), A.mul(x.i, y.r) )
  126. );
  127. },
  128.  
  129. inv = (kind x) {
  130. auto d = A.inv( A.add( A.mul(A.conj(x.i), x.i), A.mul(A.conj(x.r), x.r) ) );
  131. return kind( A.mul(d, A.conj(x.r)), A.sub(A.zero(), A.mul(d, x.i)) );
  132. },
  133.  
  134. }
  135. }
  136.  
  137. enum toString = (kind x) => (A.toString(x.r) ~ ", " ~ A.toString(x.i));
  138. }
  139.  
  140.  
  141. /**/alias Complex = G!Reals;
  142. alias Quaternion = G!Complex;/**/
  143.  
  144. static assert(isDivAlgebra!Reals && isDivAlgebra!Complex && isDivAlgebra!Quaternion);
  145.  
  146. alias id(alias token) = token;
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
Success #stdin #stdout 0s 17384KB
stdin
Standard input is empty
stdout
3
2, 0
3, 0, 0, 0