2011-02-01 12 views
8

Czy jest jakiś silnik obliczeniowy dla języka C#, który automatycznie przelicza pola zależne, gdy zmienia się wartość?Coś takiego jak silnik obliczeniowy dla C#?

Pozwól freestyle na sekundę, jestem wyobrażając sobie coś takiego ..

Field<double> quantity = Field.Create<double>("Quantity"); 
Field<double> unitCost = Field.Create<double>("Unit Cost"); 
Field<double> total = Field.Create<double>("Total"); 

total.Calculation((q,uc) => q * uc, quantity, value); 
     // would have signature something like this: 
     // void Calculation<TR,T1,T1>(Func<TR,T1,T2>, Field<T1>, Field<T2>) 

To skonfigurować pola, które propagują wartości auto-zależnych.

quantity.Value = 5.0; 
unitCost.Value = 1.5; 
Assert.That(total.Value, Is.EqualTo(7.5)); 

Oczywiście jest to prosty przykład, końcowe zastosowania będą bardziej zbliżone do obliczeń złożonego arkusza kalkulacyjnego.

Myśląc dalej byłoby wspaniale, gdyby pole/komórki obsługiwały powiadomienie o zmianie.

+3

Wyszukiwanie "reguł silnika" w Windows Workflow Foundation. –

+0

Nie wiem, czy już istnieje, ale wygląda na to, że i tak warto to zaimplementować, po prostu potrzebujesz INotifyPropertyChanging i dekompresję drzewa Expression do depedencji łącza. – Guillaume86

Odpowiedz

5

Czy widziałeś http://ncalc.codeplex.com?

Jest rozszerzalny, szybki (np. Ma własną pamięć podręczną) umożliwia dostarczanie niestandardowych funkcji i zmiennych w czasie wykonywania poprzez obsługę zdarzeń EvaluateFunction/EvaluateParameter. Przykład wyrażenia może analizować:

Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)"); 

    e.Parameters["Pi2"] = new Expression("Pi * Pi"); 
    e.Parameters["X"] = 10; 

    e.EvaluateParameter += delegate(string name, ParameterArgs args) 
    { 
     if (name == "Pi") 
     args.Result = 3.14; 
    }; 

    Debug.Assert(117.07 == e.Evaluate()); 

obsługuje również wiele danych Unicode & typu natywnie. Zawiera plik antler, jeśli chcesz zmienić gramat. Istnieje również widelec, który obsługuje MEF do ładowania nowych funkcji.

Obsługuje także operatory logiczne, łańcuchy daty/czasu i instrukcje if.

rozwiązanie

Można ewentualnie zrobić automatyczne przeliczanie wdrażając INotifyPropertyChanged potem robi coś podobnego

  • ustawić wyrażenie this.Field.Expression polu w = new wyrażenie ("Pole1 + Pole2 ");

Na notifypropertyupdated w klasie

  • dla każdego pola (z odbicia), które jest funkcją
  • jeśli to wyrażenie odnosi się do dziedziny zmienionej następnie przeliczyć zmienną.
  • na przeliczenia trzeba by obsłużyć zdarzenia EvaluateParameter użyć refleksji znalezienie odpowiedniego pola i wyodrębnić jego wartość (można buforować, aby uniknąć odbicie w razie potrzeby)
+0

Interesujący projekt - czy obsługuje zależności? to znaczyCzy mogę zbudować serię wyrażeń, które opierają się na wynikach innych wyrażeń? Jeśli są w niewłaściwej kolejności (lub jeśli później zmieniają wartość czegoś używanego przez poprzednią - czy zajmie się aktualizacją kaskadową?) Dokumentacja wydaje się unikać tematu (może po prostu szukam w niewłaściwym miejscu) – Rudu

+0

@Rudu "radzi sobie z zależnościami", obsłuży DAG wyrażeń przechodzących od pierwszego wyrażenia poprzez wyrażenia określone jako parametry do tego wyrażenia, a następnie do wyrażeń określonych jako parametry tych wyrażeń i tak dalej. W ten sposób nigdy nie uzyskasz okrężnej zależności, a kolejność obliczeń zawsze powinna być poprawna, zależność sicne jest obliczana jako pierwsza. – GreyCloud

+0

@Rudu - ostatni przykład na http://ncalc.codeplex.com/ pokazuje, jak można zagnieżdżać. Na temat kaskadowych aktualizacji. Nie wystąpią, wartość, którą otrzymasz, jest wartością obliczoną w tym czasie. Będziesz musiał uporządkować kaskadowe aktualizacje przez coś takiego jak INotifyPropertyChanged na klasie zawierającej dane: – GreyCloud

1

zadałem podobne pytanie tutaj: Truly declarative language?

O ile mi wiadomo, dopiero co usłyszałem o NCalc, zajrzę w to. Mam projekt, który w dużym stopniu opisuje to, co opisujesz, a następnie trochę jak buforowanie/cache upuszczając zmiany wartości lub strukturę modelu. Pomyśl o tym jako o skrzyżowaniu bazy danych z Excelem. Można również definiować klasy itp. I łączyć je w duże modele z milionami obiektów na wykresach, a nie tylko drzewami. Serwer kliencki itp. Istnieje również edytor modeli, w którym tworzy się modele w interfejsie użytkownika, dzięki czemu można analizować, w jaki sposób wszystkie obliczenia opierają się na sobie nawzajem.

Dlaczego dokładnie pytasz?

1

Istnieją silniki obliczeniowe parametrów skalarnych, a tam są silniki obliczeniowe wyższego poziomu dla tabel, zwykle używane w aplikacjach takich jak planowanie finansowe, obliczenia opłat i prowizji, obliczenia sieciowe i kontraktowe ...

Pozwól mi wyjaśnić to wkrótce. Rozważ następujące formuły dla skalarów:

1) z = f1(x,y) 
2) p = f2(z,n) 
3) q = f3(x,p) 
... 

i tak dalej. Konfiguracja takich funkcji i drzew zależności wymaga silnika obliczeniowego o parametrach skalarnych. Chciałbym (także) polecić następujący link dla takiego silnika obliczeniowego zapisanego w C# jako dobry punkt wyjścia: http://www.codeproject.com/Articles/246374/A-Calculation-Engine-for-NET

Jak wspomniano, istnieją również silniki obliczeniowe z funkcjami tabel, które przyjmują tabele jako parametry. Główna zasada jest jednak taka sama:

1) (T4, T5) = TableFunction1(T1, T2, T3) 
2) (T7, T8) = TableFunction2(T2, T4) 
... 

i tak dalej. Zwróć uwagę, że funkcja tabeli może zwracać wiele tabel jako dane wyjściowe, jak pokazano powyżej.

tam dwie kluczowe kwestie, których należy przestrzegać tutaj:

a) Wartości stołów T7 i T8 zależeć na stołach T2 i T4. Dlatego tabele T7 i T8 należy zaktualizować, wykonując funkcję "TableFunction2" tylko w przypadku zmiany jednego z parametrów wejściowych T2 lub T4.

Podobnie, T4 należy aktualizować tylko wtedy, gdy T1, T2 lub T3 są aktualizowane; drzewo zależności!

b) Oddzielenie bazy danych od procesu obliczeniowego: Silnik obliczeniowy musi działać niezależnie od dowolnej struktury danych lub schematu bazy danych, aby można go było zintegrować z dowolną bazą danych i strukturą danych.

można znaleźć powiązany artykuł w którym zasady te są wyjaśnione na stronie:

architektura logiczna z regułowy Kalkulacja ram http://finaquant.com/logical-architecture-of-a-rule-based-calculation-framework/1053

Teraz, C#/.NET biblioteka dla silnika obliczeniowego z tabelami. w miarę opracowywania parametrów wejściowych i wyjściowych w oparciu o te zasady.

Uwaga dla moderatorów: Usuń powyższy link, jeśli jest on traktowany jako autopromocja.

+0

Kolejny dobry punkt wyjścia: http: //www.codeproject .pl/Articles/17853/Wdrażanie-jak-formuły-silnik-formuły – tuncalik

Powiązane problemy