Skip to content
Snippets Groups Projects
gmlmip_stub.c 3.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • Thorsten Wißmann's avatar
    Thorsten Wißmann committed
    #define __STDC_LIMIT_MACROS
    #define __STDC_FORMAT_MACROS
    
    #include <utility> // for pair
    #include <vector>
    
    #include <set>
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
    
    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);
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
    }
    
    template<class T>
    
    value set2CamlList(const set<T>& vec, value (*f)(const T&)) {
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
        CAMLlocal2( cli, cons );
        cli = Val_emptylist;
    
    
        for (typename set<T>::const_reverse_iterator it = vec.rbegin();
             it != vec.rend();
             ++it)
        {
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
            cons = caml_alloc(2, 0);
    
    
            Store_field( cons, 0, f(*it) );  // head
            Store_field( cons, 1, cli );     // tail
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
    
            cli = cons;
        }
    
        return cli ;
    }
    
    
    
    
    static CAMLprim value pair2caml(const int& t) {
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
        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));
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
        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");
    }
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
    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);
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
        }
        // 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);
    
    Thorsten Wißmann's avatar
    Thorsten Wißmann committed
        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 );
    }