#define __STDC_LIMIT_MACROS #define __STDC_FORMAT_MACROS #include <utility> // for pair #include <vector> #include <set> extern "C" { #include <caml/mlvalues.h> #include <caml/alloc.h> #include <caml/memory.h> #include <caml/custom.h> } #include "GMLMIP-0.1/onestep.h" // using namespace std; extern "C" { CAMLprim value gmlRules_stub(value modalities); CAMLprim value pmlRules_stub(value modalities); } template<class T> value set2CamlList(const set<T>& vec, value (*f)(const T&)) { CAMLparam0(); CAMLlocal2( cli, cons ); cli = Val_emptylist; for (typename set<T>::const_reverse_iterator it = vec.rbegin(); it != vec.rend(); ++it) { cons = caml_alloc(2, 0); Store_field( cons, 0, f(*it) ); // head Store_field( cons, 1, cli ); // tail cli = cons; } return cli ; } static CAMLprim value pair2caml(const int& t) { CAMLparam0(); CAMLlocal1( abc ); abc = caml_alloc(2, 0); bool neg = t < 0; Store_field( abc, 0, Val_int((neg ?(-t) : t) - 1)); Store_field( abc, 1, Val_bool(!neg)); return abc; } static CAMLprim value set2caml(const set<int>& vt) { return set2CamlList(vt, pair2caml); } static CAMLprim value setset2caml(const set<set<int> >& vt) { return set2CamlList(vt, set2caml); } static void printModVec(FILE* f, const vector<pair<pair<bool,int>,int> >& modvec) { fprintf(f, "GML-Input: /\\ ("); for (int i = 0; i < modvec.size(); i++) { bool isdia = modvec[i].first.first; int cnt = modvec[i].first.second; int underl = modvec[i].second; if (i > 0) fprintf(f, ","); if (isdia) { fprintf(f, " <%d> p%d", cnt, underl); } else { fprintf(f, " [%d] p%d", cnt, underl); } } fprintf(f, " )\n"); } CAMLprim value gmlRules_stub(value modalities) { // parse caml-modalities to a C++ vector CAMLparam1( modalities ); value block = modalities; vector<pair<pair<bool,int>,int> > modvec; while (Is_block(block)) { CAMLlocal3( vpos, vcnt, vformula ); vpos = Field(Field(block, 0), 0); vcnt = Field(Field(block, 0), 1); vformula = Field(Field(block, 0), 2); modvec.push_back(make_pair(make_pair( Bool_val(vpos), Int_val(vcnt)), 1+Int_val(vformula))); block = Field(block, 1); } // Do one rule step and save result in rulevec GMLConclusion rulevec = gmlmip_onestep_gml(modvec); // convert rulevec into ocaml list of pairs CAMLlocal1( res ); res = set2CamlList(rulevec, setset2caml); CAMLreturn( res ); } CAMLprim value pmlRules_stub(value modalities) { // parse caml-modalities to a C++ vector CAMLparam1( modalities ); value block = modalities; vector<pair<pair<bool,pair<int,int> >,int> > modvec; while (Is_block(block)) { CAMLlocal4( vpos, vnom, vdenom, vformula ); vpos = Field(Field(block, 0), 0); vnom = Field(Field(block, 0), 1); vdenom = Field(Field(block, 0), 2); vformula = Field(Field(block, 0), 3); modvec.push_back(make_pair(make_pair( Bool_val(vpos), make_pair(Int_val(vnom),Int_val(vdenom))), 1+Int_val(vformula))); block = Field(block, 1); } // Do one rule step and save result in rulevec GMLConclusion rulevec = gmlmip_onestep_pml(modvec); // convert rulevec into ocaml list of pairs CAMLlocal1( res ); res = set2CamlList(rulevec, setset2caml); CAMLreturn( res ); }