fmod BASICOPS2JSON is
  inc MAUDE2JSON-AUX .


****    ****    ****   BasicOps  ****    ****    ****    ****    ****    
**** just collect name sort and metadata, include modname for tracking

  vars opspecs str badstr badstr1 mdstr : String .
  vars modnames usedids : QidList .
  var modname qid  : Qid .
  var alist sexpl : SexpL .
  var bindings : TBinds .
  var next : FindResult .
  var sexp? : Sexp? .
  var onotes : Notes .

  op basicOpsTemplate : -> String .
  eq basicOpsTemplate = "{\n %opspecs \n}" . 

  op basicOps2json : QidList String ~> String .
  eq basicOps2json(nil,opspecs) =
       fillTemplate(basicOpsTemplate, "%opspecs" :~ opspecs) .
  eq basicOps2json(modname modnames,opspecs) = 
         basicOps2json(modnames,
                       opdecls2json(upOpDecls(modname,false),
											              modname,opspecs ,"")) .


**** only the used ops
  op basicOps2json : Notes QidList String ~> String .
	op usedOpDecls : Notes Qid -> OpDeclSet .
	op usedOpDeclsX : QidList OpDeclSet OpDeclSet -> OpDeclSet .

  eq basicOps2json(onotes, nil,opspecs) =
       fillTemplate(basicOpsTemplate, "%opspecs" :~ opspecs) .

  ceq basicOps2json(onotes, modname modnames,opspecs) = 
         basicOps2json(onotes, modnames,
           (if (modname == 'PROTEINOPS)
            then opdecls2json(allods:OpDeclSet,none,ods:OpDeclSet,modname,opspecs,"")
            else opdecls2json(ods:OpDeclSet,modname, opspecs, "") fi)) 
        if allods?:[OpDeclSet] := upOpDecls(modname,false)
				/\ allods:OpDeclSet := (if allods?:[OpDeclSet] :: OpDeclSet 
                                then allods?:[OpDeclSet]
                                else (none).OpDeclSet fi )
        /\ ods?:[OpDeclSet] := usedOpDecls(onotes,modname) 
        /\ ods:OpDeclSet := (if ods?:[OpDeclSet] :: OpDeclSet 
                                then ods?:[OpDeclSet]
                                else (none).OpDeclSet fi )        
        .

	ceq usedOpDecls(onotes,'LOCATIONOPS) =
	      usedOpDeclsX(usedids, upOpDecls('LOCATIONOPS,false),none ) 
     if ql(usedids) := lookupd(onotes,"usedLocNames",ql(nil)) .
	ceq usedOpDecls(onotes,'MODIFICATIONOPS) =
	      usedOpDeclsX(usedids, upOpDecls('MODIFICATIONOPS,false),none) 
     if ql(usedids) := lookupd(onotes,"usedModifications",ql(nil)) .
	ceq usedOpDecls(onotes,modname) =
	      usedOpDeclsX(usedids, upOpDecls(modname,false),none)  
     if ql(usedids) := lookupd(onotes,"usedEntities",ql(nil)) [owise]  .

	eq usedOpDeclsX(usedids,none,uods:OpDeclSet) = uods:OpDeclSet .
	ceq usedOpDeclsX(usedids,od:OpDecl ods:OpDeclSet,uods:OpDeclSet) = 
	    usedOpDeclsX(usedids,ods:OpDeclSet,uods:OpDeclSet uods1:OpDeclSet)
	  if (op qid : nil -> t:Type [atts:AttrSet].) := od:OpDecl
	 /\ uods1:OpDeclSet := (if occurs(qid,usedids) then od:OpDecl else none fi) .
	eq usedOpDeclsX(usedids,od:OpDecl ods:OpDeclSet,uods:OpDeclSet) = 
	    usedOpDeclsX(usedids,ods:OpDeclSet,uods:OpDeclSet) [owise] . 
	    *** skip non constants

**** end only the used ops
  op basicOpTemplate : -> String .
  eq basicOpTemplate =
"%name:{\"stype\" : \"basicOp\",\n\
\t \"name\" : %name,\n\
\t \"modname\" : %modname,\n\
\t \"metadata\" : %metadata\n}" 
.

  op opdecls2json : OpDeclSet Qid String String -> String .
  op opdecl2json : Qid Qid SexpL -> String .

  eq opdecls2json(none,modname,str,badstr) =
****        str + sep?(str,",\n") + badstr . 
     str 
		 + (if ((str == "") or (badstr == "")) then "" else ",\n" fi) 
		 + badstr .
  ceq opdecls2json(od:OpDecl ods:OpDeclSet,modname,str,badstr) = 
      opdecls2json(ods:OpDeclSet,
                    modname,
                    str + sep?(str,",\n") + opdecl2json(qid,modname,alist),
                    badstr1)
  if (op qid : nil -> t:Type [atts:AttrSet].) := od:OpDecl
  /\ mdstr := getMetaData(atts:AttrSet)
  /\ ixs(next,sexp?) := readSexp(mdstr,0,length(mdstr)) 
  /\ alist := (if sexp? :: Sexp then sexp2l(sexp?) else nil fi) 
              [a("sort") a(string(t:Type))]   ---- keeping actual maude sort
  /\ badstr1 := 
       (if (sexp? :: Sexp or mdstr == "")
        then badstr 
        else badstr + sep?(badstr,",\n")
             + fillTemplate(badTemplate,
                            (("%name" :~ squote("!!!" + string(qid))), 
                             ("%badstr" :~ squote(mdstr)) )) 
        fi) .

*** skip non-constants
  eq opdecls2json(od:OpDecl ods:OpDeclSet,modname,str,badstr) = 
      opdecls2json(ods:OpDeclSet,modname,str,badstr) [owise]  .


**** for OpDecls of entities with parts.
**** 14may03 fixing duplicate potential
  op opdecls2json : OpDeclSet OpDeclSet OpDeclSet Qid String String -> String .
  eq opdecls2json(all:OpDeclSet,done:OpDeclSet,none,modname,str,badstr) =
****        str + sep?(str,",\n") + badstr . 
     str 
		 + (if ((str == "") or (badstr == "")) then "" else ",\n" fi) 
		 + badstr .
  ceq opdecls2json(all:OpDeclSet,done:OpDeclSet,od:OpDecl ods:OpDeclSet, 
                   modname,str,badstr) = 
      opdecls2json(all:OpDeclSet,done:OpDeclSet od:OpDecl, ods1:OpDeclSet, 
                    modname,
                    str + sep?(str,",\n") + opdecl2json(qid,modname,alist),
                    badstr1)
  if (op qid : nil -> t:Type [atts:AttrSet].) := od:OpDecl
  /\ mdstr := getMetaData(atts:AttrSet)
  /\ ixs(next,sexp?) := readSexp(mdstr,0,length(mdstr)) 
  /\ alist := (if sexp? :: Sexp then sexp2l(sexp?) else nil fi) 
              [a("sort") a(string(t:Type))]   ---- keeping actual maude sort
  /\ su:SexpL := alget(alist,"subunits")
  /\ ms:SexpL := alget(alist,"members")
  /\ pof:SexpL := alget(alist,"partof")
  /\ ods1:OpDeclSet := getParts(all:OpDeclSet,done:OpDeclSet,
                               (su:SexpL ms:SexpL pof:SexpL),ods:OpDeclSet)
  /\ badstr1 := 
       (if (sexp? :: Sexp or mdstr == "")
        then badstr 
        else badstr + sep?(badstr,",\n")
             + fillTemplate(badTemplate,
                            (("%name" :~ squote("!!!" + string(qid))), 
                             ("%badstr" :~ squote(mdstr)) )) 
        fi) .


  op getParts : OpDeclSet OpDeclSet SexpL OpDeclSet -> OpDeclSet .
  eq getParts(all:OpDeclSet,done:OpDeclSet,nil,ods:OpDeclSet) = ods:OpDeclSet .
  eq getParts(all:OpDeclSet,done:OpDeclSet,a(o:String) sexpl,ods:OpDeclSet) = 
       getParts(all:OpDeclSet,done:OpDeclSet,sexpl,
                ods:OpDeclSet 
                 (if getConstOpDecls(ods:OpDeclSet done:OpDeclSet,
                                     qid(o:String), none) == none
                  then getConstOpDecls(all:OpDeclSet, qid(o:String),none)
                  else none fi)) .

  op getConstOpDecls : OpDeclSet Qid OpDeclSet -> OpDeclSet .
  eq getConstOpDecls( (op qid : nil -> t:Type [atts:AttrSet].) ods0:OpDeclSet,
                      qid, ods:OpDeclSet ) =
       getConstOpDecls(ods0:OpDeclSet,qid,
                       ods:OpDeclSet (op qid : nil -> t:Type [atts:AttrSet].)) .

  eq getConstOpDecls(ods0:OpDeclSet,qid,ods:OpDeclSet) = ods:OpDeclSet [owise] .


*** skip non-constants
  eq opdecls2json(all:OpDeclSet,done:OpDeclSet, od:OpDecl ods:OpDeclSet, 
                  modname,str,badstr) = 
      opdecls2json(all:OpDeclSet,done:OpDeclSet od:OpDecl, 
                   ods:OpDeclSet,modname,str,badstr) [owise]  .


  ceq opdecl2json(qid,modname,alist) =
      fillTemplate(basicOpTemplate,bindings)
  if bindings := (("%name" :~ squote(string(qid))),
                  ("%modname" :~ squote(string(modname))),                 
                  ("%metadata" :~ alist2json(alist,nil,"")) )  .

endfm