PolyLink
A library to allow manipulation of geometry from within Mathematica
 All Classes Namespaces Files Functions Variables Properties
KernelDispatch.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Diagnostics;
5 using System.Linq;
6 using System.Text;
7 using System.Threading.Tasks;
8 using Wolfram.NETLink;
9 
10 namespace PolyLink
11 {
16  {
17  public static int KernelWait = 1;
18 
19  private readonly IKernelLink _kernel;
20 
21  public KernelDispatch()
22  {
23  //Set up kernel link
24  _kernel = MSingle.Kernel;
25  //_kernel.WaitAndDiscardAnswer();
26  }
27 
31  public IKernelLink Kernel
32  {
33  get { return _kernel; }
34  }
35 
41  public IKernelOperation this[string s]
42  {
43  get
44  {
45  return new KernelOperation(_kernel, s);
46  }
47  }
48  }
49 
50  public interface IKernelOperation
51  {
55  string Command { get; }
56 
60  IKernelLink Kernel { get; }
61 
67  KernelOperation Format(params object[] args);
68 
74  KernelOperation Bracket(params object[] args);
75 
81  KernelOperation Bracket<T>(IEnumerable<T> args);
82 
86  object EvalObject();
87 
91  Expr Eval();
92 
96  Func<Expr, Expr> EvalFunc();
97 
102  }
103 
105  {
106  private readonly string _command;
107  private readonly IKernelLink _kernel;
108 
109  public KernelOperation(IKernelLink kernel, string command)
110  {
111  _kernel = kernel;
112  _command = command;
113  }
114 
115  public string Command
116  {
117  get { return _command; }
118  }
119 
120  public IKernelLink Kernel
121  {
122  get { return _kernel; }
123  }
124 
125  public void CheckArgs<T>(IEnumerable<T> args)
126  {
127  if (args.Any(t => t is KernelOperation))
128  {
129  throw new ArgumentException("Never feed a KernelOperation into another KernelOperation. You probably forgot an Eval somewhere.");
130  }
131  }
132 
133  public KernelOperation Format(params object[] args)
134  {
135  CheckArgs(args.AsEnumerable());
136  return new KernelOperation(Kernel, String.Format(Command, args.Select(o => "(" + o.ToString() + ")").ToArray()));
137  }
138 
139  public KernelOperation Bracket(params object[] args)
140  {
141  CheckArgs(args.AsEnumerable());
142  return Bracket(args.AsEnumerable());
143  }
144 
145  public KernelOperation Bracket<T>(IEnumerable<T> args)
146  {
147  args = args.ToArray();
148  CheckArgs(args);
149  return new KernelOperation(Kernel,
150  String.Format("{0}[{1}]",_command, String.Join(",", args))
151  );
152  }
153 
154  public object EvalObject()
155  {
156  MaybePrint();
157  Kernel.Evaluate(_command);
158  Kernel.WaitForAnswer();
159  var e = Kernel.GetExpr();
160  //Console.WriteLine("Result of EvalObject was {0} characters big", e.ToString().Length);
161  Kernel.Evaluate(e);
162  Kernel.WaitForAnswer();
163  return Kernel.GetObject();
164 
165  }
166 
167 
168 
169  public Expr Eval()
170  {
171  MaybePrint();
172  Kernel.Evaluate(_command);
173  Kernel.WaitForAnswer();
174  Expr e = Kernel.GetExpr();
175  //Console.WriteLine("Result of Eval was {0} characters big", e.ToString().Length);
176  return e;
177  }
178 
179  public Func<Expr, Expr> EvalFunc()
180  {
181  var k = Kernel;
182  var s = _command;
183  return delegate(Expr expr)
184  {
185  k.Evaluate(String.Format("{0}[{1}]", s, expr));
186  k.WaitForAnswer();
187  return k.GetExpr();
188  };
189  }
190 
192  {
193  return new KernelOperation(Kernel, String.Format("RootReduce[{0}]",Command));
194  }
195 
196 
197  private static int x = 0;
198 
199  private void MaybePrint()
200  {
201  x++;
202  if (x%1000 == 0)
203  Console.WriteLine("Computation number: {0}", x);
204  }
205  }
206 }