Converting WCNF to Mosel format
|
|
Type: | Programming |
Rating: | 3 (intermediate) |
Description: | The 'cnf2mos' tool transforms a SAT or MAXSAT problem instance in CNF or WCNF format to a Mosel SAT/MAXSAT formulation. It also accepts compressed files (gzip format). The tool can be deployed as an executable (requires a C compiler): mosel comp cnf2mos.mos -o deploy.exe:cnf2mosTHe excutable needs to be invoked by specifying the name of the file to be converted as a required argument. Alternatively the program can be run as a standard Mosel model, e.g. from the command line: mosel cnf2mos.mos F=name_of_file_to_convertThe resulting Mosel file can be executed in all usual ways, it requires the Xpress Optimizer for solving the MAXSAT problem via MIP functionality. |
File(s): | cnf2mos.mos |
Data file(s): | Rounded_BTWBNSL_asia_100_1_3.scores_TWBound_2.wcnf.gz |
|
cnf2mos.mos |
(!****************************************************** Mosel Example Programs ====================== file cnf2mos.mos ```````````````` A (W)CNF to MOS converter. (c) 2020 Fair Isaac Corporation author: Y.Colombani, Jun. 2020 *******************************************************!) model cnf2mos version 0.0.1 uses 'mmsystem','deploy' parameters MAXLEN=80 ! Maximum length of lines (for printing the objective) end-parameters declarations ! The following text is added before calling 'minimise' before_solve=` setparam('xprs_loadnames', true) ` src,dest,fname,prefix: text ! Handling of filenames line,objtext: text ! Aux. texts nbvar,nbcl,nbwc: integer ! Various counters whrd: real ! Weight value for binding clauses iswcnf: boolean ! Whether problem is a WCNF curlen: integer ! Line length indicator wcfile="tmp:"+newmuid ! Subroutines defined by this program procedure skipcomment(l:text) procedure parseoptions(l:text) procedure parseclause(l:text) procedure displayclause(lst:list of integer) procedure displaynotclause(lst:list of integer) end-declarations ! Check for filename argument and display 'usage' banner if none is found if argc=1 then writeln("Usage: mosel cnf2mos -- filename (.cnf[.gz] or .wcnf[.gz])") exit(1) elif argc<>2 then writeln("Usage: cnf2mos filename (.cnf[.gz] or .wcnf[.gz])") exit(1) else fname:=argv(2) end-if ! Check whether input file is compressed src:=pathsplit(SYS_FNAME,fname) if endswith(src,".gz") then prefix:="zlib.gzip:" dest:=src-".gz" else dest:=src end-if ! Supported extensions: .cnf and .wcnf if endswith(dest,".cnf") then dest:=(dest-".cnf")+".mos" elif endswith(dest,".wcnf") then dest:=(dest-".wcnf")+".mos" else dest+=".mos" end-if ! Don't overwrite existing file if getfstat(dest)<>0 then writeln("File '", dest, "' exists - aborting") exit(2) end-if ! Start the transformation fopen(prefix+fname,F_INPUT) writeln("Generating '", dest, "'...") fopen(dest,F_OUTPUT) ! Header text for generated file writeln("! Generated by cnf2mos v",getparam("model_version")," from '",src,"'"); writeln("model sat\nuses 'mmxprs'\n") ! Process the clauses nbcl:=1 curlen:=5 while(readtextline(line)>0 and nbcl>0) do case getchar(line,1) of 99: ! c skipcomment(line) 112: ! p parseoptions(line) else parseclause(line) end-case end-do writeln ! Objective function for MAXSAT case, solver call and solution reporting if iswcnf and objtext.size>0 then if nbwc>0 then writeln("RW:=1..",nbwc,"\nfinalise(RW)") fclose(F_OUTPUT) fcopy(wcfile,0,dest,F_APPEND) fopen(dest,F_OUTPUT+F_APPEND) writeln end-if deltext(objtext,1,1) ! remove leading '+' writeln("Obj:=",objtext,"\n") write(before_solve) writeln("minimise(Obj)") else write(before_solve) writeln("minimise(1)") end-if write(` if getprobstat<>XPRS_OPT then writeln("Problem is infeasible") else writeln("Solution:") `) if iswcnf then writeln(' writeln(" Obj=", getobjval)') end-if writeln(` forall(i in R | b(i).sol) write(" b(", i, ")") writeln end-if end-model `) !**************** Implementation of subroutines **************** ! Skip comment line procedure skipcomment(l:text) deltext(l,1,1) write("! ",l) end-procedure ! Read options/instance parameters and generate Mosel declarations procedure parseoptions(l:text) type:=parsetext(l,3) if type<>"cnf" and type<>"wcnf" then fclose(F_INPUT) fclose(F_OUTPUT) writeln("Unsupported format '",type,"' - aborting") exit(3) end-if asproc(nextfield(l)) nbvar:=parseint(l) asproc(nextfield(l)) nbcl:=parseint(l) if type="wcnf" then iswcnf:=true asproc(nextfield(l)) whrd:=parsereal(l) end-if writeln("public declarations\n R=1..",nbvar,"\n b: array(R) of boolvar") if iswcnf then writeln(" RW: range\n w: array(RW) of boolvar") end-if writeln("end-declarations\n") writeln("writeln('Model generated from file \"",src,"\"')") writeln("writeln('Problem size:')") writeln("writeln(' variables: ",nbvar,"')") writeln("writeln(' clauses: ",nbcl,"')") if iswcnf then writeln("writeln(' top weight:",whrd,"')") end-if writeln end-procedure ! Read a clause procedure parseclause(l:text) declarations lst:list of integer firstval:boolean txtline:text end-declarations setparam("sys_endparse",0) firstval:=true while(nextfield(l)) if iswcnf and firstval then firstval:=false weight:=parsereal(l) else lst+=[parseint(l)] end-if if iswcnf and weight<>whrd then wtxt:=if(weight<>1,text(weight)+"*",text("")) if lst.size=2 then ! only 1 value and 0 if lst(1)<0 then txtline:=wtxt+"b("+(-lst(1))+").var" else txtline:=wtxt+"getvar(not b("+lst(1)+"))" end-if else ! 2 or more values nbwc+=1 txtline:=wtxt+"w("+nbwc+").var" fopen(wcfile,F_OUTPUT+F_APPEND) write("w(",nbwc,")=(") displaynotclause(lst) writeln(")") fclose(F_OUTPUT) end-if if curlen+txtline.size+1>MAXLEN then curlen:=4+txtline.size objtext+=text("+\n ")+txtline else curlen+=txtline.size+1 objtext+=text("+")+txtline end-if else displayclause(lst) writeln end-if nbcl-=1 end-procedure ! Output a clause in Mosel format procedure displayclause(lst:list of integer) declarations firstdone:boolean end-declarations forall(i in lst|i<>0) do if firstdone then write(" or ") else firstdone:=true end-if if i<0 then write("not b(",-i,")") else write("b(",i,")") end-if end-do end-procedure ! Output the negation of a clause in Mosel format procedure displaynotclause(lst:list of integer) declarations firstdone:boolean end-declarations forall(i in lst|i<>0) do if firstdone then write(" and ") else firstdone:=true end-if if i<0 then write("b(",-i,")") else write("not b(",i,")") end-if end-do end-procedure end-model |
© 2001-2024 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.