" also works.
- Fixed several bugs that occured when
reading lines longer than 8192 bytes long.
- New function "zpl_read_with_args" to allow
processing of command line defines, -s seed and
multi file input in embedded apllications.
- Funktions argmin/argmax implemented:
argmin(5) in { 1 .. 100 } : abs(50 - i)
will generate the set containing the indices of the
five smallest |50-i| evaluations. Be aware that the
the result is not neseccarily unambiguous since the index
set i snot ordered. For example
argmin in { 1 .. 10 } : 5.
In case of argmin(1) the "(1)" can be omitted.
argmax is the same the other way around.
- It is now possible to initialise parameters without giving the
index tuple explicitly. Writing
param a[{1..4}*{1..3}] := read "matrix.dat" as "n+" comment "#";
with for example a file like
1 2 3 4
5 6 7 8 # here is a comment
9 10 11 12
or with a file like this
1 2 3 4 5 6 7 8 9 10 11 12
will result in
a[1,1] = 1 ... a[4,3] = 12
Excess elements in the files are ignored.
If there are not enough elements in the file, the elements in the
parameter will be undefined, or set to default if present.
Use "s+" for strings.
- Check was missing if the parameter from a file is indeed a number.
Bug fixed regarding the field number given for tuple fields errors.
- Input from stringfiles is now possible. This
allows to embed Zimpl programs into other programs
without using any external files.
- Small bug in multi iterator validation fixed.
2.04 30. Jan 2006 Release
- Funktion random(minimum, maximum) implemented, which
generates (hopefully) uniformly distributed random values
between minimum and maximum. (not very well tested)
- A warning 203 is generated in many cases when the
indexing tuple is completely fixed.
- Objective function inversion warning for MPS files is
now only issued once.
- A constant value in the objective function is now translated
automatically into a variable __ObjOffset. This works on
all output formats.
- powerset() is now also generating the empty set.
- It is now possible to write:
UNION in I with i > 5 : A[i];
INTER in I with i > 5 : A[i];
to get the union or intersetection of all the involved sets.
- When initialising an indexed set with a list any "with" clause
on the set expresion was ignored.
- Error 195 was the same as 135. It is now all 135.
Error 195 has a new meaning.
- It is now possible to read a single value by
param n := read "huhu.dat" as "4n" skip 4 use 1
The above would read the fourth value in the fifth
line of the file huhu.dat.
- Fixed error in description of -n in -h output and some typos
in the documentation.
- Fixed problem when reading DOS format data files.
The CR at the end of the line is now removed instead of being
attached to the last field.
- Fixed bug with IN operator and Rangesets.
- It is now possible to build sets by indexing an
expression: { in I with i != 3 : p[i] }; or
{ in A with i != 3 : };
- Special Ordered Sets (SOS) implemented. Thanks Daniel.
- Changed a problem with the -n cf option due to a change in
the LP file format specification.
- Tabs are now allowed as separators after keywords (set, param, ...)
- Control characters (notably CR from DOS files) are now
ignored (treated as space) on input.
- Zimpl is now build as a library to simplify incorporation
into other programs.
2.03 2. Mar 2005 Release
- If -v=0 ist set, most warnings are now suppressed.
- Documentation improved.
- Applying union, minus, intersection, or symmetric
difference to two sets with tuples that have different component
types will now result in a useful error message.
- Fixed a bug that let unknown names evaluate to a member of a set.
Example: subto c1: forall in I do w[k] <= 1;
did not result in an error.
- Fixed a bug that made it possible to put an undefined name in a set.
- There is now a difference between "to" and "..".
"to" tries to do exactly what is requested possibly resulting in
an empty set. ".." does as before its best to produce a range.
- Fixed Bug in print command appearing in connection with default clause.
- Fixed Bug in handling of set products.
- Decreased memory consumption of hash tables.
- Slightly faster string hashing.
- Improved error handling for wrong components in sets.
2.02 15. May 2004 Release
- New function ordinal ord(s,t,c) implemented.
While there is no specific order, all sets have one.
That is ord will evaluate to the c-th component of the t-th
tuple in set s. ord({1..10}*{"a","b"}, 3, 1) is something
between 1 and 10, possibly 3. But doing
do forall in {1..card(I)} do print ord(E,i,1);
will print every element in I if it is one dimensional.
- Improved detection of incorrect initialization of sets and params.
- Bug in mod function fixed. Before mod gave the wrong result,
if the two numbers had factors in common.
- New -m switch that will write a CPLEX MST file with MIP starting values.
- Complete new Set implementation.
- If verbose is >= 3, the local variable
stack is printed if an error occurs.
- Makefile changed to support Mac OS-X.
- New -V flag to show the version number.
-h now also prints the banner text.
- man page created
2.01 29. Oct 2003 Release
- min/max over a indexed set of numbers, will now issue a warning,
if the index set is empty.
- Preprocessing is now switched on with the -O (optimize) switch.
- Fixed a major bug that occured, if two number
were subtracted from a constraint like in x - 5 + 3 >= 1
- Documentation update. Many spelling errors removed.
do print and do check statements documented.
- vif and vabs implemented. See documentation for details.
- set implementation changed. Generated powersets
and subsets do not use a hash table anymore.
This should reduce memory consumption, but
might slow things down a little bit.
- xor implemented.
- Fixed bug in presolve that resulted in fixed
variables not removed.
- Missing linefeed in hum format fixed.
- Implemented "check" statement.
- Implemented the "do" statement. This changes the
syntax for print. It is now "do print".
Now "do forall in I do print i; " is possible.
- Error 163 now shows the location of the error.
(Always start of the line ;-)
- It is now possible to define non indexed parameters
on the command line. -Dpeng=12 is equivalent to
param peng := 12; in the Zimpl file.
- <,<=,>=,> for strings implemented.
- Function sqrt() implemented.
- Functions log(), ln(), exp() reactivated.
- Some error cases of parameter input
were not handled correctly.
- Table input for parameter implemented.
- if for contstraints and summands implemented.
- if for set expressions implemented.
- Self defined functions implemented.
2.00 17. Sep 2003 Release
- Function sgn(expr) implemented.
- Fixed a bug in the set range routine. Now ranges with
negative numbers are allowed.
- Fixed bugs with MPS format.
- New output format "hum" for -t parameter generates unmangled human readable,
maschine unreadble LP format output. This replaces the -m switch.
- Changed -v switch to -v0..3 and also the outputs that appear by default.
- It is now possible to omit the .zpl extension on the input files.
- Changed output routine, so that it should work
even with with braindead OS like Windoof.
Also allowed to use a different directory separator.
- Trailing text on the last line should now draw a message.
- Bug fixed, that resulted in an unreadable LP file
if the index set of the variable has negative numbers.
- Fixed bug, that cut extensions from basenames given by -o .
- Fixed internal bug with bool not function.
- We now get an error message instead of an abort()
if the initialisation list of an parameter is empty.
- New functions min/max that take a list of expression,
like min(2, 5, a[4], b[7] / 2); (a and b are parameters)
- Included zlib. It is now possible to read in .gz transparantly.
- New function exists() that looks if a set has
at least one member, e.g. exists( in I with i > 5 )
should be equivatent to card( { in I with i > 5 }) > 0
- Better diagnosis if a variable/parameter/set name is used a second time.
- It is now possible to have contraint/obective names
that are identical to variable/parameter/set names.
- Changed gererated numbers for long names to hex. This needs less space.
- Names are now 8 characters long for MPS output,
but 16 for LPF. This is accroding to the CPLEX 7.0
specification. Starting at 8.0 it is possible to
have 255 character long names, we want to stay
compatible with the older versions.
- Changed the syntax for set initialisation.
if an indexset is assigned it has to be included in
braces like set A := { in I with i > 5 }
- It is now possible to write { in A with a > 5 }
whenever a set is needed. This means also it is now
possible to nest indexsets, like in
{ in { in C with k > 2 } with i mod 2 == 0 }
- Ranges are now possible: 7 <= 5x + 6 y <= 99
(MPS output not yet here)
- First presolve implemented.
-p now switches on presolve, -F does what -p did before.
- Fixed bug that empty constraints were ignored,
even with a non zero right hand side.
- Changed everything to rational numbers (GMP)
(Funktions exp, log, ln, rand are out of order)
- Fixed that variable which were not part of a constraint,
were omitted in the Bounds section of the LPF/MPS file.
- new -m switch to write unmangled lp file.
1.05 23. Mar 2003 Release
- make check now works.
- Removed senseless default in non indexed parameter.
- New Makefile that allows different architectures in parallel.
- Replaced rbt functions by a hash table. Mainly for portability.
- Fixed bug in print statement that accured when trying to
print a indexed set, without giving an index.
- It is now allowed to use a WITH clause in the initialisation
of parameters, variables and sets, like
param x[ in I with i > 5] := i * 4;
- Fixed bug that accured in the following case:
param x[<"1", i> in A] := i * 4;
- The number of elements in a set is now estimated and the
hash table is sized accordingly. This should same some
memory especially with the powerset function.
- Fixed bug in param initialisation which set the type
of the param always to NUMB.
- Changes param initialsation. STRG values are allowed
within indexed intialiszations.
- Changed IF command. It can now handle (in principle) all
types as return values, but only NUMB, STRG, NAME are
allowed by the parser.
- Change the implementation of SUM command. Major speedup.
- Implemented random(min, max) generates a random number between min and max.
At the moment rand() is used, but this will change.
- It is now possible to have a default value for a parameter.
param p[A] := <1> 1, <2> 2 default 99
will declare all p[i] with i in A and not 1 or 2 to return 99.
- Corrected a typo, that resulted in .orf files instead of .ord
- sym_lookup is now resolved in the scanner (speedup).
- Added new flag -p "filter" which pipes the output
through the filter, enabling for example compression.
(Daniels idea)
- The output files will be created in the current directory,
if no -o flag is given. If it is present the name and path
given will be used.
- New possible value infinit/-infinity for upper/lower bounds.
- We might display a warning if writing to a file fails somewhere in the middle.
- When writing MPS there is a warning if the problem was inverted.
- Warning about different dimension tuples prints tuples.
- Tabs are now allowed at the start of a statement.
- Non integral variable bounds for integral Variables are
Warned about and fixed.
- Bug fixed, that would not only set one variable from integer
to binary, but all that would follow in the set also.
- New function powerset(N) implemented. This generates all subsets
of N. Example: set S[] = powerset(N);
- New statement print started.
- Function subsets(N, k) implemented. This generates all
subsets of N with k elements. It is now possible to leave out
the indexing subset in a set declaration. So
set S[] := subsets(N, 3);
is valid. Additional the new function indexset(S) returns the
index set of S.
- Indexed Sets implemented.
- added "!" factorial function.
- log, ln, exp where missing in the parser and the documentation.
1.04 20. Oct 2002 Release
- Bug fixed in storage of variable and constraint names.
- Grammar fixed, since trailing '*' expr of vexpr where not parsed.
- Only variables that are written to the LP are written to the
".tbl" file.
- Fixed a bug that would discard free variables with non zero costs.
- Changed the output of the ".tbl" file. Now also the long constraint
names are enclosed in doublequotes.
- New options -n cm|cn|cf that control how the constraints in the
LPF/MPS file are named. "cm" will number them 1..n with a "c"
in front. "cn" will use the name supplied in the subto statement
and number them 1..n within the statement. "cf" will use the
name of the subto, then a 1..n number like in "cm" and then append
all the local variables from the forall statements.
(It is open if the "f" in "cf" stands for "full" or for "fuegenschuh".)
- Grammar changed again, to allow x/3 as shorthand for x * 1/3
- Changed grammar again, to get rid of conflicts.
- A union B does no longer warn about dublicate elements.
This should also speed up oder set operations a bit.
- The read template syntax is checked more precice.
- Integer variables with bounds [0,1] are automatically changed
to binary variables.
- New function proj(set,tuple) wich projects a set to the elements
of the tuple given. Example:
set A := { 1 to 9 } * { 10 to 19 } * { "A","B" };
set B := proj(A, <3,1>)
will give: <"A",1>, <"A",2"> ... <"B",9>
- Bug fixed, dublicate constraint names now give an error message.
- New functions log(x), ln(x) and exp(x), meaning
logarithm to base 10, natural logarithm and e^x.
- It is now possible to have variables on both sides of an
inequality. "x[1] <= y[1]" is now supported.
- Changed the parser to (hopefully) correct parse inequalites in
all possible varietes. This includes nested sums and coefficents
at all places.
1.03 31. Jul 2002 Release
- A division by Zero now gives an error message
(instead of an exception or whatever)
- It is now possible to assign a qualified set expression
to a set, like
set C := in A * B with i < j;
- It is now possible to nest "forall" statements. This
can vastly reduce the memory needed, because it is no
longer neccessary to build big cross products to loop
over them.
So instead of
forall in I * J with i < j do
it is possible to write
forall in I do forall in J with i < j do
- elems where now reused, this reduces the memory needed.
- changed to not copy in principle const objects, this should
have improved speed.
1.02 05. Jul 2002 Release
- new functions FLOOR(expr) and CEIL(expr) which find the
next integer down and up.
- Bug fixed in MPS output that lets zimpl write BOUND lines
for variables that are not used.
- new flag -r that write a CPLEX branching order file (.ord).
Two new attributes for variables:
"priority expr" sets the branching priority for the variable.
"startval expr" sets the start values for the variable
- new function ABS(expr) that returns the absolut value of expr.
- new function CARD(set) that computes the cardinality of a set.
- memory leak pugged, that occured when summing over a restricted set.
- added possiblility to initialise parameter per set element,
the same way as variables.
- the row scaling factor is now also printed in the .tbl file.
- Added "attributes" to the constraints. At the moment the following
are understood:
scale : scales the constraint before writing the LP file.
After scaling the absolut larges coefficient will be one.
separate : Means "this constraint should be separated".
At the moment, such constraints are written in an "User constraint"
section in the LP-File. But CPlex does not recognise this.
- "sum" is now also valid for expressions without variables.
- Fixed error in LPF Writing Routine, that would write "Inf"
instead of "+Inf".
- Wrong template in read now gives an error message instead of
an segment violation.
1.01 30. Oct 2001 Bug fix release
- Added several missing const's to the code.
- Unterminated string constants where not reported as errors.
This led to very irritating behavior. Fixed.
- Since it is possible that string type set members include spaces,
the "real" name in the .tbl file is now surrounded by doublequotes.
(I am not totally sure this is a good idea. Maybe I should just,
change all spaces to underscores.)
- It is now possible to write -x[3] in a constraint. Before
it was neccessary to write -1*x[3].
- Changed the field splitting for the read statement. The FS
keyword is gone. Read now tries to do the "right" thing.
Look at the documentation for details.
- When writing LP-format files, one's as coefficents are
no longer written. This makes the files somewhat shorter.
- -d (Debug) Option is no longer be ignored.
- Default field separators for the read statement are
now , <;> and ( is new).
- Fixed one minor malloc error with the include statement.
- Removed all uses of alloca() for better AIX compatibility.
- String valued parameters now work.
1.00 09. Oct 2001 Initial release
zimpl-3.3.6/Makefile 0000644 0014172 0006025 00000020754 13371051600 014221 0 ustar bzfschlo optimi #* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#* *
#* File....: Makefile *
#* Name....: Zimpl Makefile *
#* Author..: Thorsten Koch *
#* Copyright by Author, All rights reserved *
#* *
#* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#*
#* Copyright (C) 2005-2018 by Thorsten Koch
#*
#* This program is free software; you can redistribute it and/or
#* modify it under the terms of the GNU General Public License
#* as published by the Free Software Foundation; either version 2
#* of the License, or (at your option) any later version.
#*
#* This program is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program; if not, write to the Free Software
#* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#*
#
.PHONY: all depend clean lint doc doxygen check valgrind libdbl coverage
ARCH := $(shell uname -m | \
sed \
-e s/sun../sparc/ \
-e s/i.86/x86/ \
-e s/i86pc/x86/ \
-e s/amd64/x86_64/ \
-e s/IP../mips/ \
-e s/9000..../hppa/ \
-e s/Power\ Macintosh/ppc/ \
-e s/00........../pwr4/)
OSTYPE := $(shell uname -s | \
tr '[:upper:]' '[:lower:]' | \
tr '/' '_' | \
sed \
-e s/cygwin.*/cygwin/ \
-e s/irix../irix/ \
-e s/windows.*/windows/ \
-e s/mingw.*/mingw/)
HOSTNAME := $(shell uname -n | tr '[:upper:]' '[:lower:]')
VERSION = 3.3.6
VERBOSE = false
SHARED = false
STATIC = false
ZLIB = true
LINK = static
OPT = opt
COMP = gnu
CC = gcc
CC_o = -o #
LINKCC = gcc
LINKCC_o = -o #the white space is important
LIBEXT = .a
YACC = bison
LEX = flex
DCC = gcc
LINT = pclp64_linux # _debug
CPPCHECK = cppcheck
AR = ar cr
AR_o =
RANLIB = ranlib
DOXY = doxygen
VALGRIND = valgrind --tool=memcheck --leak-check=full \
--leak-resolution=high --show-reachable=yes
SRCDIR = src/zimpl
BINDIR = bin
LIBDIR = lib
LINTCONF = /opt/pclint/config
CPPFLAGS = -I$(SRCDIR)/.. -DVERSION='"$(VERSION)"'
CFLAGS = -O
LDFLAGS = -lgmp -lm
YFLAGS = -d -t -v
LFLAGS = -d
ARFLAGS =
DFLAGS = -MM
GCCWARN = -Wall -W -Wpointer-arith -Wcast-align -Wwrite-strings \
-Wstrict-prototypes -Wmissing-prototypes -Winline \
-Wmissing-declarations -Wshadow -Waggregate-return \
-Wno-unused -Wno-unknown-pragmas
ifeq ($(ZLIB),true)
LDFLAGS += -lz
else
CPPFLAGS += -DWITHOUT_ZLIB
endif
ifeq ($(SHARED),true)
LINK = shared
endif
ifeq ($(STATIC),true)
LINK = static
endif
BASE = $(OSTYPE).$(ARCH).$(COMP).$(OPT)
OBJDIR = obj/O.$(OSTYPE).$(ARCH).$(COMP).$(LINK).$(OPT)
NAME = zimpl
BINNAME = $(NAME)-$(VERSION).$(OSTYPE).$(ARCH).$(COMP).$(LINK).$(OPT)
LIBNAME = $(NAME)-$(VERSION).$(BASE)
LIBRARY = $(LIBDIR)/lib$(LIBNAME)$(LIBEXT)
LIBRARYDBL = $(LIBDIR)/lib$(LIBNAME).dbl$(LIBEXT)
LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE)$(LIBEXT)
LIBDBLLINK = $(LIBDIR)/lib$(NAME).$(BASE).dbl$(LIBEXT)
BINARY = $(BINDIR)/$(BINNAME)
BINARYDBL = $(BINDIR)/$(BINNAME).dbl
BINLINK = $(BINDIR)/$(NAME).$(BASE)
BINSHORTLINK = $(BINDIR)/$(NAME)
DEPEND = $(SRCDIR)/depend
#-----------------------------------------------------------------------------
OBJECT = zimpl.o xlpglue.o zlpglue.o \
ratlpstore.o ratlpfwrite.o ratmpswrite.o ratmstwrite.o \
ratordwrite.o ratpresolve.o
LIBBASE = blkmem.o bound.o code.o conname.o define.o elem.o entry.o \
hash.o heap.o idxset.o inst.o iread.o list.o \
load.o local.o metaio.o mmlparse2.o mmlscan.o mono.o \
mshell.o prog.o random.o rdefpar.o source.o \
setempty.o setpseudo.o setlist.o setrange.o setprod.o \
setmulti.o set4.o stmt.o stkchk.o strstore2.o symbol.o \
term2.o tuple.o vinst.o zimpllib.o
LIBOBJ = $(LIBBASE) gmpmisc.o numbgmp.o
LIBDBLOBJ = $(LIBBASE) numbdbl.o
OBJXXX = $(addprefix $(OBJDIR)/,$(OBJECT))
LIBXXX = $(addprefix $(OBJDIR)/,$(LIBOBJ))
LIBDBLXXX = $(addprefix $(OBJDIR)/,$(LIBDBLOBJ))
OBJSRC = $(addprefix $(SRCDIR)/,$(OBJECT:.o=.c))
LIBSRC = $(addprefix $(SRCDIR)/,$(LIBOBJ:.o=.c)) #(SRCDIR)/numbdbl.c
#-----------------------------------------------------------------------------
include make/make.$(OSTYPE).$(ARCH).$(COMP).$(OPT)
-include make/local/make.$(HOSTNAME)
-include make/local/make.$(HOSTNAME).$(COMP)
-include make/local/make.$(HOSTNAME).$(COMP).$(OPT)
#-----------------------------------------------------------------------------
FLAGS += $(USRFLAGS)
OFLAGS += $(USROFLAGS)
CFLAGS += $(USRCFLAGS) $(USROFLAGS)
LDFLAGS += $(USRLDFLAGS)
ARFLAGS += $(USRARFLAGS)
DFLAGS += $(USRDFLAGS)
ifeq ($(VERBOSE),false)
.SILENT: $(LIBRARY) $(LIBLINK) $(BINARY) $(BINLINK) $(BINSHORTLINK) \
$(SRCDIR)/mmlparse2.c $(SRCDIR)/mmlscan.c $(OBJXXX) $(LIBXXX) $(LIBDBLXXX)
endif
all: $(LIBRARY) $(LIBLINK) $(BINARY) $(BINLINK) $(BINSHORTLINK)
double: $(LIBRARYDBL) $(LIBDBLLINK) $(BINARYDBL) # $(BINLINK) $(BINSHORTLINK)
$(LIBLINK): $(LIBRARY)
@rm -f $@
cd $(dir $@) && ln -s $(notdir $(LIBRARY)) $(notdir $@)
$(LIBDBLLINK): $(LIBRARYDBL)
@rm -f $@
cd $(dir $@) && ln -s $(notdir $(LIBRARYDBL)) $(notdir $@)
$(BINLINK) $(BINSHORTLINK): $(BINARY)
@rm -f $@
cd $(dir $@) && ln -s $(notdir $(BINARY)) $(notdir $@)
$(BINARY): $(OBJDIR) $(BINDIR) $(OBJXXX) $(LIBRARY)
@echo "-> linking $@"
ifeq ($(COMP), msvc)
$(LINKCC) $(CFLAGS) $(OBJXXX) $(LIBRARY) $(LDFLAGS) $(LINKCC_o)$@
else
$(LINKCC) $(CFLAGS) $(OBJXXX) -L$(LIBDIR) -l$(LIBNAME) $(LDFLAGS) $(LINKCC_o)$@
endif
$(BINARYDBL): $(OBJDIR) $(BINDIR) $(OBJXXX) $(LIBRARYDBL)
@echo "-> linking $@"
$(LINKCC) $(CFLAGS) $(OBJXXX) -L$(LIBDIR) -l$(LIBNAME).dbl $(LDFLAGS) $(CC_o)$@
$(LIBRARY): $(OBJDIR) $(LIBDIR) $(LIBXXX)
@echo "-> generating library $@"
-rm -f $(LIBRARY)
$(AR) $(AR_o)$@ $(LIBXXX) $(ARFLAGS)
ifneq ($(RANLIB),)
$(RANLIB) $@
endif
libdbl: $(LIBRARYDBL) $(LIBDBLLINK)
$(LIBRARYDBL): $(OBJDIR) $(LIBDIR) $(LIBDBLXXX)
@echo "-> generating library $@"
-rm -f $(LIBRARYDBL)
$(AR) $@ $(LIBDBLXXX) $(ARFLAGS)
$(RANLIB) $@
$(SRCDIR)/mmlparse2.c: $(SRCDIR)/mmlparse2.y $(SRCDIR)/mme.h
@echo "-> generating yacc parser $@"
$(YACC) $(YFLAGS) -o $@ $<
$(SRCDIR)/mmlscan.c: $(SRCDIR)/mmlscan.l $(SRCDIR)/mme.h
@echo "-> generating lex scanner $@"
$(LEX) $(LFLAGS) -o$@ $<
lint: $(OBJSRC) $(LIBSRC)
$(LINT) $(LINTCONF)/co-gcc.lnt $(SRCDIR)/project2.lnt \
-I$(LINTCONF) -I$(SRCDIR) -dNO_MSHELL -dVERSION='"$(VERSION)"' $^
cppcheck: $(OBJSRC) $(LIBSRC)
$(CPPCHECK) $(CPPFLAGS) -I/usr/include -I/usr/include/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu/bits -I/usr/include/x86_64-linux-gnu/sys -I/usr/include/linux -I/usr/lib/gcc/x86_64-linux-gnu/5/include --inline-suppr --suppressions-list=src/cppcheck.txt --enable=warning,style,performance,portability,information $^
doc:
cd doc; make -f Makefile
doxygen:
cd doc; $(DOXY) $(NAME).dxy
check:
cd check; \
/bin/sh ./check.sh ../$(BINARY)
valgrind:
cd check; \
/bin/sh ./check.sh "$(VALGRIND) ../$(BINARY)"
coverage:
-ln -s ../../src $(OBJDIR)
-mkdir -p gcov
lcov -d $(OBJDIR) -z
make OPT=gcov check
lcov -d $(OBJDIR) -c >gcov/z.capture
lcov -d $(OBJDIR) -r gcov/z.capture "*mmlscan.c" "*mmlparse2.c" >gcov/zimpl.capture
genhtml -o gcov gcov/zimpl.capture
-rm gcov/z.capture
$(OBJDIR):
@echo "** creating directory \"$@\""
@-mkdir -p $(OBJDIR)
$(LIBDIR):
@echo "** creating directory \"$@\""
@-mkdir -p $(LIBDIR)
$(BINDIR):
@echo "** creating directory \"$@\""
@-mkdir -p $(BINDIR)
clean:
-rm -rf $(OBJDIR)/* $(BINARY) $(LIBRARY) $(LIBRARYDBL) $(LIBLINK) $(BINLINK) $(BINSHORTLINK)
depend:
$(SHELL) -ec '$(DCC) $(DFLAGS) $(CPPFLAGS) $(OBJSRC) $(LIBSRC) \
| sed '\''s|^\([0-9A-Za-z\_]\{1,\}\)\.o|$$\(OBJDIR\)/\1.o|g'\'' \
>$(DEPEND)'
-include $(DEPEND)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
@echo "-> compiling $@"
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< $(CC_o)$@
# --- EOF ---------------------------------------------------------------------
zimpl-3.3.6/Makefile.nmake 0000644 0014172 0006025 00000011570 13371051600 015307 0 ustar bzfschlo optimi # $Id: Makefile,v 1.82 2011/10/31 08:48:56 bzfkocht Exp $
#* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#* *
#* File....: Makefile *
#* Name....: Zimpl Makefile *
#* Author..: Thorsten Koch *
#* Copyright by Author, All rights reserved *
#* *
#* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#*
#* Copyright (C) 2005-2018 by Thorsten Koch
#*
#* This program is free software; you can redistribute it and/or
#* modify it under the terms of the GNU General Public License
#* as published by the Free Software Foundation; either version 2
#* of the License, or (at your option) any later version.
#*
#* This program is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program; if not, write to the Free Software
#* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#*
#
#.PHONY: all clean
ARCH = x86
OSTYPE = win
VERSION = 3.3.3
VERBOSE = 0
LINK = normal
OPT = opt
COMP = msvc
CC = cl
AR = lib
LD = link
SRCDIR = src
BINDIR = bin
LIBDIR = lib
CPPFLAGS = /DVERSION=\"$(VERSION)\" \
/I$(SRCDIR) /I$(SRCDIR)\WIN \
/Dpopen=_popen /Dpclose=_pclose /DWITH_PCRE=1 \
/Ilib\zlib \
/Ilib\pcre \
/Ilib\mpir.$(ARCH) \
/D_CRT_SECURE_NO_WARNINGS
CFLAGS =
ARFLAGS = /nologo
LIBS = lib\libz.$(ARCH).lib \
lib\libpcre.$(ARCH).lib \
lib\libmpir.$(ARCH).lib
LDFLAGS = /NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD /STACK:67108864 /OPT:REF /OPT:ICF /NOLOGO
BASE = $(OSTYPE).$(ARCH).$(COMP).$(OPT)
OBJDIR = obj\O.$(OSTYPE).$(ARCH).$(COMP).$(LINK).$(OPT)
NAME = zimpl
BINNAME = $(NAME)-$(VERSION).$(OSTYPE).$(ARCH).$(COMP).$(LINK).$(OPT)
LIBNAME = $(NAME)-$(VERSION).$(BASE)
LIBRARY = $(LIBDIR)\lib$(LIBNAME).lib
BINARY = $(BINDIR)\$(BINNAME).exe
DEPEND = $(SRCDIR)\depend
#-----------------------------------------------------------------------------
OBJECT = $(OBJDIR)\zimpl.obj $(OBJDIR)\xlpglue.obj $(OBJDIR)\zlpglue.obj \
$(OBJDIR)\ratlpstore.obj $(OBJDIR)\ratlpfwrite.obj $(OBJDIR)\ratmpswrite.obj $(OBJDIR)\ratmstwrite.obj \
$(OBJDIR)\ratordwrite.obj $(OBJDIR)\ratpresolve.obj
LIBBASE = $(OBJDIR)\getopt.obj $(OBJDIR)\blkmem.obj $(OBJDIR)\bound.obj $(OBJDIR)\code.obj $(OBJDIR)\conname.obj \
$(OBJDIR)\define.obj $(OBJDIR)\elem.obj $(OBJDIR)\entry.obj \
$(OBJDIR)\hash.obj $(OBJDIR)\heap.obj $(OBJDIR)\idxset.obj $(OBJDIR)\inst.obj $(OBJDIR)\iread.obj $(OBJDIR)\list.obj \
$(OBJDIR)\load.obj $(OBJDIR)\local.obj $(OBJDIR)\metaio.obj $(OBJDIR)\mmlparse2.obj $(OBJDIR)\mmlscan.obj $(OBJDIR)\mono.obj \
$(OBJDIR)\mshell.obj $(OBJDIR)\prog.obj $(OBJDIR)\random.obj $(OBJDIR)\rdefpar.obj $(OBJDIR)\source.obj \
$(OBJDIR)\setempty.obj $(OBJDIR)\setpseudo.obj $(OBJDIR)\setlist.obj $(OBJDIR)\setrange.obj $(OBJDIR)\setprod.obj \
$(OBJDIR)\setmulti.obj $(OBJDIR)\set4.obj $(OBJDIR)\stmt.obj $(OBJDIR)\stkchk.obj $(OBJDIR)\strstore2.obj $(OBJDIR)/symbol.obj \
$(OBJDIR)\term2.obj $(OBJDIR)\tuple.obj $(OBJDIR)\vinst.obj $(OBJDIR)\zimpllib.obj
LIBOBJ = $(LIBBASE) $(OBJDIR)\gmpmisc.obj $(OBJDIR)\numbgmp.obj
#-----------------------------------------------------------------------------
!include make/nmake.$(OSTYPE).$(ARCH).$(COMP).$(OPT)
#-----------------------------------------------------------------------------
!if $(VERBOSE) == 0
!CMDSWITCHES +S
!endif
all: $(LIBRARY) $(BINARY)
$(BINARY): $(OBJDIR) $(BINDIR) $(OBJECT) $(LIBRARY)
@echo "-> linking $@"
$(LD) $(LDFLAGS) /OUT:$@ $(OBJECT) $(LIBRARY) $(LIBS)
$(LIBRARY): $(OBJDIR) $(LIBDIR) $(LIBOBJ)
@echo "-> generating library $@"
@del $(LIBRARY)
$(AR) $(ARFLAGS) /OUT:$@ $(LIBOBJ)
$(OBJDIR):
@echo "** creating directory \"$@\""
@mkdir $(OBJDIR)
$(LIBDIR):
@echo "** creating directory \"$@\""
@mkdir $(LIBDIR)
$(BINDIR):
@echo "** creating directory \"$@\""
@mkdir $(BINDIR)
clean:
del /Q $(OBJDIR)\*.* $(BINARY) $(LIBRARY)
!include $(DEPEND)
{$(SRCDIR)}.c{$(OBJDIR)}.obj:
@echo "-> compiling $@"
$(CC) $(CPPFLAGS) $(CFLAGS) /c $< /Fo$@
$(OBJDIR)\getopt.obj: $(SRCDIR)\WIN\getopt.c $(SRCDIR)\WIN\getopt.h
$(CC) $(CPPFLAGS) $(CFLAGS) /c $(SRCDIR)\WIN\getopt.c /Fo$@
# --- EOF ---------------------------------------------------------------------
zimpl-3.3.6/make/ 0000755 0014172 0006025 00000000000 13303265236 013475 5 ustar bzfschlo optimi zimpl-3.3.6/make/make.linux.x86.gnu.valgrind 0000644 0014172 0006025 00000001055 13303265233 020512 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.gnu.valgrind,v 1.12 2014/03/03 08:36:28 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O3 -m32 -march=pentiumpro -g -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m32 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86.gnu.opt-gccold 0000644 0014172 0006025 00000001017 13303265233 020735 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.gnu.opt-gccold,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3 -m32 -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m32 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.mingw.x86.msvc.opt 0000644 0014172 0006025 00000001271 13303265236 017652 0 ustar bzfschlo optimi CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES -D_DLL
CFLAGS = -O3
LDFLAGS = -NODEFAULTLIB:LIBCMT -NODEFAULTLIB:LIBCMTD -STACK:67108864 -OPT:REF -OPT:ICF -NOLOGO -LTCG
CC = cl
CC_o = -Fo
CFLAGS =
LINKCC = link
LINKCC_o = -OUT:
AR = lib -nologo
AR_o = /OUT:
RANLIB =
LIBEXT = .lib
CPPFLAGS += -Dpopen=_popen -Dpclose=_pclose -Dinline=_inline -DNDEBUG -DWITH_PCRE=1 -D_WIN32 -W2 -wd4272 -Ox -nologo
CPPFLAGS += -Isrc/WIN -Ilib/pcre -Ilib/zlib -Ilib/pcre -Ilib/mpir.$(ARCH)
LDFLAGS += lib/libz.$(ARCH).$(OPT).lib \
lib/libpcre.$(ARCH).$(OPT).lib \
lib/libmpir.$(ARCH).$(OPT).lib
LIBBASE += getopt.o zimpl-3.3.6/make/make.darwin.x86_64.gnu.opt 0000644 0014172 0006025 00000001033 13301553023 020133 0 ustar bzfschlo optimi #--- $Id: make.darwin.x86_64.gnu.opt,v 1.8 2014/03/03 08:36:28 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS += -O3 -m64
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m64 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS = -Bstatic -lgmp -lm
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.irix.mips.sgi.dbg 0000644 0014172 0006025 00000000327 13301553023 017564 0 ustar bzfschlo optimi #--- $Id: make.irix.mips.sgi.dbg,v 1.6 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DFREEMEM -Dinline=""
CFLAGS = -fullwarn -g
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/nmake.win.x86.msvc.opt 0000644 0014172 0006025 00000000207 13301553023 017472 0 ustar bzfschlo optimi CPPFLAGS = $(CPPFLAGS) /Dinline=_inline /DWIN32 /DNDEBUG
CFLAGS = $(CFLAGS) /W2 /wd4274 /Ox /nologo
LDFLAGS = $(LDFLAGS) /LTCG
zimpl-3.3.6/make/make.darwin.ppc.gnu.opt 0000644 0014172 0006025 00000000332 13301553023 017760 0 ustar bzfschlo optimi #--- $Id: make.darwin.ppc.gnu.opt,v 1.7 2014/03/03 08:36:28 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.sparc.gnu.dbg 0000644 0014172 0006025 00000000345 13301553023 020127 0 ustar bzfschlo optimi #--- $Id: make.sunos.sparc.gnu.dbg,v 1.6 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -g -fident $(GCCWARN)
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.sparc.gnu.opt 0000644 0014172 0006025 00000000332 13301553023 020171 0 ustar bzfschlo optimi #--- $Id: make.sunos.sparc.gnu.opt,v 1.8 2014/03/03 08:36:28 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86.intel.dbg 0000644 0014172 0006025 00000000637 13301553023 017762 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.intel.dbg,v 1.14 2014/01/12 11:07:04 bzfkocht Exp $
CC = icc
CPPFLAGS += -DFREEMEM
CFLAGS = -g -fp-model precise -w2 -Wcheck \
-par_report0 -vec_report0 \
-wd111,171,279,981,1173,1419,1684
LDFLAGS = -lgmp -lm
# -wd383,444,810
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
#ifeq ($(LINK),shared)
#LINK = normal
#endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.freebsd.x86.gnu.opt 0000644 0014172 0006025 00000000377 13301553023 017762 0 ustar bzfschlo optimi #--- $Id: make.freebsd.x86.gnu.opt,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -I/usr/local/include -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3
LDFLAGS = -L/usr/local/lib -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.cygwin.x86_64.gnu.opt 0000644 0014172 0006025 00000000376 13301553023 020160 0 ustar bzfschlo optimi #--- $Id: make.cygwin.x86.gnu.opt,v 1.9 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DWINDOWS -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3 -march=pentiumpro $(GCCWARN)
LDFLAGS = -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.x86_64.gnu.opt 0000644 0014172 0006025 00000000356 13301553023 020025 0 ustar bzfschlo optimi #--- $Id: make.sunos.x86_64.gnu.opt,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3 -m64 -mtune=native
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.hp-ux.hppa.hp.dbg 0000644 0014172 0006025 00000000367 13301553023 017463 0 ustar bzfschlo optimi #--- $Id: make.hp-ux.hppa.hp.dbg,v 1.7 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DFREEMEM -Dinline="" -Dfinite=isfinite
CFLAGS = -z -g +DD64 +W21,486,474
LDFLAGS = -noshared -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.cygwin.x86_64.gnu.dbg 0000644 0014172 0006025 00000000343 13301553023 020104 0 ustar bzfschlo optimi #--- $Id: make.cygwin.x86.gnu.dbg,v 1.9 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DWINDOWS -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O -g $(GCCWARN)
LDFLAGS = -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86.gnu.dbg 0000644 0014172 0006025 00000001017 13301553023 017431 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.gnu.dbg,v 1.14 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES -Dinline=
CFLAGS = -O0 -m32 -g -fident -ftrapv $(GCCWARN)
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m32 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.linux.x86.gnu.gcov 0000644 0014172 0006025 00000001042 13301553023 017631 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.gnu.gcov,v 1.10 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DCOVERAGE -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -m32 -g -fprofile-arcs -ftest-coverage
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m32 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.mingw.x86.msvc.dbg 0000644 0014172 0006025 00000001255 13303265236 017606 0 ustar bzfschlo optimi CPPFLAGS += -DNO_MSHELL -D__NO_MATH_INLINES -D_DLL
CFLAGS =
LDFLAGS = -NODEFAULTLIB:LIBCMT -NODEFAULTLIB:LIBCMTD -STACK:67108864 -OPT:REF -OPT:ICF -NOLOGO -LTCG
CC = cl
CC_o = -Fo
CFLAGS =
LINKCC = link
LINKCC_o = -OUT:
AR = lib -nologo
AR_o = /OUT:
RANLIB =
LIBEXT = .lib
CPPFLAGS += -Dpopen=_popen -Dpclose=_pclose -Dinline=_inline -DNDEBUG -DWITH_PCRE=1 -D_WIN32 -W2 -wd4272 -Ox -nologo
CPPFLAGS += -Isrc/WIN -Ilib/pcre -Ilib/zlib -Ilib/pcre -Ilib/mpir.$(ARCH)
LDFLAGS += lib/libz.$(ARCH).$(OPT).lib \
lib/libpcre.$(ARCH).$(OPT).lib \
lib/libmpir.$(ARCH).$(OPT).lib
LIBBASE += getopt.o
zimpl-3.3.6/make/make.linux.x86.gnu.prf 0000644 0014172 0006025 00000001052 13303265233 017470 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.gnu.prf,v 1.11 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -march=pentiumpro -m32 -g -pg $(GCCWARN) -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m32 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.x86.gnu.opt 0000644 0014172 0006025 00000000751 13301553023 017513 0 ustar bzfschlo optimi #--- $Id: make.sunos.x86.gnu.opt,v 1.8 2014/03/03 08:36:28 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -Bstatic
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86_64.gnu.gcov 0000644 0014172 0006025 00000001054 13303265233 020152 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.gnu.gcov,v 1.10 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DCOVERAGE -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -m64 -g -fprofile-arcs -ftest-coverage -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m64 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86_64.gnu.prf 0000644 0014172 0006025 00000001053 13303265233 020002 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.gnu.prf,v 1.2 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O -m64 -mtune=native -g -pg $(GCCWARN) -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m64 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.mingw.x86.gnu.opt 0000644 0014172 0006025 00000000365 13303265233 017473 0 ustar bzfschlo optimi #--- $Id: make.mingw.x86.gnu.opt,v 1.3 2014/03/03 08:36:28 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3 -std=gnu99
LDFLAGS = -lgmp -lpcreposix -lpcre -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86_64.eko.opt 0000644 0014172 0006025 00000000417 13301553023 020000 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.eko.opt,v 1.6 2014/01/12 11:07:04 bzfkocht Exp $
CC = pathcc
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -std=c99 -D_POSIX_C_SOURCE=2 -march=auto -m64 -O3 -ipa
LDFLAGS = -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86_64.eko.dbg 0000644 0014172 0006025 00000000443 13301553023 017731 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.eko.dbg,v 1.6 2014/01/12 11:07:04 bzfkocht Exp $
CC = pathcc
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -std=c89 -Dinline= -D_POSIX_C_SOURCE=2 -march=em64t -m64 -O0 -g $(GCCWARN)
LDFLAGS = -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.darwin.x86.intel.dbg 0000644 0014172 0006025 00000000507 13301553023 020103 0 ustar bzfschlo optimi #--- $Id: make.darwin.x86.intel.dbg,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CC = icc
CPPFLAGS += -DFREEMEM
CFLAGS = -g -fp-model precise -w2 -Wcheck \
-par_report0 -vec_report0 \
-wd111,171,279,981,1173,1419,1684
LDFLAGS = -lgmp -lm -Bstatic
# -wd383,444,810
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86_64.clang.dbg 0000644 0014172 0006025 00000001267 13303265233 020251 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.gnu.dbg,v 1.7 2014/01/12 11:07:04 bzfkocht Exp $
CC = clang
CPPFLAGS += -DFREEMEM #-D__NO_MATH_INLINES
CFLAGS = -O0 -m64 -g -Weverything -Wno-padded -Wno-switch-enum -Wno-covered-switch-default -Wno-static-in-inline -Wno-pedantic -Wno-format-nonliteral -Wno-shorten-64-to-32 -Wno-disable-macro-expansion -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
ifeq ($(LINK),shared)
LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
AR = gcc -m64 -shared -o # the trailing space is important
ARFLAGS = $(LDFLAGS)
RANLIB = true
endif
ifeq ($(LINK),static)
LDFLAGS += -static
endif
zimpl-3.3.6/make/make.mingw.x86_64.msvc.dbg 0000644 0014172 0006025 00000001255 13303265236 020117 0 ustar bzfschlo optimi CPPFLAGS += -DNO_MSHELL -D__NO_MATH_INLINES -D_DLL
CFLAGS =
LDFLAGS = -NODEFAULTLIB:LIBCMT -NODEFAULTLIB:LIBCMTD -STACK:67108864 -OPT:REF -OPT:ICF -NOLOGO -LTCG
CC = cl
CC_o = -Fo
CFLAGS =
LINKCC = link
LINKCC_o = -OUT:
AR = lib -nologo
AR_o = /OUT:
RANLIB =
LIBEXT = .lib
CPPFLAGS += -Dpopen=_popen -Dpclose=_pclose -Dinline=_inline -DNDEBUG -DWITH_PCRE=1 -D_WIN64 -W2 -wd4272 -Ox -nologo
CPPFLAGS += -Isrc/WIN -Ilib/pcre -Ilib/zlib -Ilib/pcre -Ilib/mpir.$(ARCH)
LDFLAGS += lib/libz.$(ARCH).$(OPT).lib \
lib/libpcre.$(ARCH).$(OPT).lib \
lib/libmpir.$(ARCH).$(OPT).lib
LIBBASE += getopt.o
zimpl-3.3.6/make/make.cygwin.x86.gnu.dbg 0000644 0014172 0006025 00000000344 13301553023 017574 0 ustar bzfschlo optimi #--- $Id: make.cygwin.x86.gnu.dbg,v 1.9 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DWINDOWS -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O -g $(GCCWARN)
LDFLAGS = -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.osf1.alpha.compaq.opt 0000644 0014172 0006025 00000000347 13301553023 020344 0 ustar bzfschlo optimi #--- $Id: make.osf1.alpha.compaq.opt,v 1.10 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DNDEBUG -DNO_MSHELL -Dinline=""
CFLAGS = -O4 -fast
LDFLAGS = -non_shared -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.x86.opt 0000644 0014172 0006025 00000000357 13301553023 016725 0 ustar bzfschlo optimi #--- $Id: make.sunos.x86.opt,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DNDEBUG -DNO_MSHELL -Dinline=""
CFLAGS = -fast -xprefetch=auto -xipo=2
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.freebsd.x86_64.gnu.opt 0000644 0014172 0006025 00000000402 13301553023 020260 0 ustar bzfschlo optimi #--- $Id: make.freebsd.x86_64.gnu.opt,v 1.2 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -I/usr/local/include -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3
LDFLAGS = -L/usr/local/lib -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.x86.dbg 0000644 0014172 0006025 00000000327 13301553023 016654 0 ustar bzfschlo optimi #--- $Id: make.sunos.x86.dbg,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DFREEMEM -Dinline=""
CFLAGS = -g -xcheck=stkovf
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.irix.mips.sgi.opt 0000644 0014172 0006025 00000000330 13301553023 017624 0 ustar bzfschlo optimi #--- $Id: make.irix.mips.sgi.opt,v 1.7 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DNDEBUG -Dinline=""
CFLAGS = -O2 -mips4 -IPA
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.win.x86.mingw-cross.opt 0000644 0014172 0006025 00000000500 13301553023 020610 0 ustar bzfschlo optimi #--- $Id: make.win.x86.mingw-cross.opt,v 1.8 2014/03/03 08:36:28 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES -DWITH_PCRE -DPCRE_STATIC
CFLAGS = -O3 -march=pentiumpro -g
LDFLAGS = -lpcreposix -lpcre -lgmp -lm -static
BINARY = $(BINDIR)/$(TARGET).exe
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.aix.pwr4.ibm.opt 0000644 0014172 0006025 00000000414 13301553023 017346 0 ustar bzfschlo optimi #--- $Id: make.aix.pwr4.ibm.opt,v 1.9 2010/06/10 19:42:42 bzfkocht Exp $
CC = xlc
CPPFLAGS += -DNDEBUG -DNO_MSHELL -Dinline="" \
-DLHT_BUCKETS=50000017U -DUSE_FSYNC
CFLAGS = -O3 -q64 -qmaxmem=-1 \
-qarch=auto -qtune=auto -qcache=auto \
-qsuppress=1506-732
zimpl-3.3.6/make/make.osf1.alpha.compaq.dbg 0000644 0014172 0006025 00000000401 13301553023 020265 0 ustar bzfschlo optimi #--- $Id: make.osf1.alpha.compaq.dbg,v 1.9 2010/06/10 19:42:42 bzfkocht Exp $
CC = cc
CPPFLAGS += -DFREEMEM -Dinline=""
CFLAGS = -std1 -w0 -gall -check \
-msg_disable strctpadding,nestincl,ignorecallval,unusedincl,unnecincl,hexoctunsign,questcompare2
zimpl-3.3.6/make/make.mingw.x86_64.msvc.opt 0000644 0014172 0006025 00000001271 13303265236 020163 0 ustar bzfschlo optimi CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES -D_DLL
CFLAGS = -O3
LDFLAGS = -NODEFAULTLIB:LIBCMT -NODEFAULTLIB:LIBCMTD -STACK:67108864 -OPT:REF -OPT:ICF -NOLOGO -LTCG
CC = cl
CC_o = -Fo
CFLAGS =
LINKCC = link
LINKCC_o = -OUT:
AR = lib -nologo
AR_o = /OUT:
RANLIB =
LIBEXT = .lib
CPPFLAGS += -Dpopen=_popen -Dpclose=_pclose -Dinline=_inline -DNDEBUG -DWITH_PCRE=1 -D_WIN64 -W2 -wd4272 -Ox -nologo
CPPFLAGS += -Isrc/WIN -Ilib/pcre -Ilib/zlib -Ilib/pcre -Ilib/mpir.$(ARCH)
LDFLAGS += lib/libz.$(ARCH).$(OPT).lib \
lib/libpcre.$(ARCH).$(OPT).lib \
lib/libmpir.$(ARCH).$(OPT).lib
LIBBASE += getopt.o zimpl-3.3.6/make/make.aix.pwr4.ibm.dbg 0000644 0014172 0006025 00000000345 13301553023 017303 0 ustar bzfschlo optimi #--- $Id: make.aix.pwr4.ibm.dbg,v 1.9 2010/06/10 19:42:42 bzfkocht Exp $
CC = xlc
CPPFLAGS += -DFREEMEM -Dinline="" -DUSE_FSYNC
CFLAGS = -g -q64 -qmaxmem=-1 -bnoquiet -qsuppress=1506-732 \
-qflttrap -qcheck=all
#-qwarn64
zimpl-3.3.6/make/make.mingw.x86.gnu.dbg 0000644 0014172 0006025 00000000401 13303265233 017414 0 ustar bzfschlo optimi #--- $Id: make.mingw.x86.gnu.dbg,v 1.2 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DWINDOWS -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O -g $(GCCWARN) -std=gnu99
LDFLAGS = -lgmp -lpcreposix -lpcre -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/nmake.win.x86_64.msvc.dbg 0000644 0014172 0006025 00000000201 13301553023 017727 0 ustar bzfschlo optimi CPPFLAGS = $(CPPFLAGS) /Dinline= /DWIN64
CFLAGS = $(CFLAGS) /W4 /Zi /wd4001 /wd4127 /wd4206 /wd4701 /wd4702 /wd4274 /nologo
zimpl-3.3.6/make/make.freebsd.x86.gnu.dbg 0000644 0014172 0006025 00000000422 13301553023 017703 0 ustar bzfschlo optimi #--- $Id: make.freebsd.x86.gnu.dbg,v 1.2 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -I/usr/local/include -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -g -fident -ftrapv $(GCCWARN)
LDFLAGS = -L/usr/local/lib -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.x86.sun.dbg 0000644 0014172 0006025 00000000333 13301553023 017455 0 ustar bzfschlo optimi #--- $Id: make.sunos.x86.sun.dbg,v 1.6 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DFREEMEM -Dinline=""
CFLAGS = -g -xcheck=stkovf
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.x86.sun.opt 0000644 0014172 0006025 00000000363 13301553023 017526 0 ustar bzfschlo optimi #--- $Id: make.sunos.x86.sun.opt,v 1.6 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DNDEBUG -DNO_MSHELL -Dinline=""
CFLAGS = -fast -xprefetch=auto -xipo=2
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.sunos.x86_64.gnu.dbg 0000644 0014172 0006025 00000000353 13301553023 017754 0 ustar bzfschlo optimi #--- $Id: make.sunos.x86_64.gnu.dbg,v 1.2 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -m64 -g -fident $(GCCWARN)
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.darwin.ppc.gnu.dbg 0000644 0014172 0006025 00000000323 13301553023 017712 0 ustar bzfschlo optimi #--- $Id: make.darwin.ppc.gnu.dbg,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O -g $(GCCWARN)
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/nmake.win.x86.msvc.dbg 0000644 0014172 0006025 00000000201 13301553023 017416 0 ustar bzfschlo optimi CPPFLAGS = $(CPPFLAGS) /Dinline= /DWIN32
CFLAGS = $(CFLAGS) /W4 /Zi /wd4001 /wd4127 /wd4206 /wd4701 /wd4702 /wd4274 /nologo
zimpl-3.3.6/make/make.linux.x86.intel.opt 0000644 0014172 0006025 00000000577 13301553023 020033 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.intel.opt,v 1.14 2014/01/12 11:07:04 bzfkocht Exp $
CC = icc
CPPFLAGS += -DNDEBUG -DNO_MSHELL
CFLAGS = -O3 -ip -fp-model precise -w1 -par_report0 -vec_report0 \
-wd1173
LDFLAGS = -lgmp -lm -static
#ifeq ($(LINK),shared)
#LINK = normal
#endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86_64.intel.opt 0000644 0014172 0006025 00000000570 13301553023 020335 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.intel.opt,v 1.4 2014/01/12 11:07:04 bzfkocht Exp $
CC = icc
CPPFLAGS += -DNDEBUG -DNO_MSHELL
CFLAGS = -O3 -ip -fp-model precise -w1 -par_report0 -vec_report0 \
-wd1173
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
#ifeq ($(LINK),shared)
#LINK = normal
#endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.sunos.sparc.sun.dbg 0000644 0014172 0006025 00000000336 13301553023 020143 0 ustar bzfschlo optimi #--- $Id: make.sunos.sparc.sun.dbg,v 1.11 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DFREEMEM -Dinline=""
CFLAGS = -g -xcheck=stkovf
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.win.x86.mingw-cross.dbg 0000644 0014172 0006025 00000000456 13301553023 020554 0 ustar bzfschlo optimi #--- $Id: make.win.x86.mingw-cross.dbg,v 1.6 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES -DWITH_PCRE -DPCRE_STATIC
CFLAGS = -O -g $(GCCWARN)
LDFLAGS = -lpcreposix -lpcre -lgmp -lm -static
BINARY = $(BINDIR)/$(BINNAME).exe
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86.gnu.opt 0000644 0014172 0006025 00000001015 13303265236 017505 0 ustar bzfschlo optimi #--- $Id: make.linux.x86.gnu.opt,v 1.15 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3 -m32 -mtune=native -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m32 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
#LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.darwin.x86.gnu.opt 0000644 0014172 0006025 00000000656 13301553023 017634 0 ustar bzfschlo optimi CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m32 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS = -Bstatic -lgmp -lm
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.hp-ux.hppa.hp.opt 0000644 0014172 0006025 00000000400 13301553023 017515 0 ustar bzfschlo optimi #--- $Id: make.hp-ux.hppa.hp.opt,v 1.8 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DNDEBUG -DNO_MSHELL -Dinline="" -Dfinite=isfinite
CFLAGS = +O3 +DD64 +W21,486,474
LDFLAGS = -noshared -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86_64.gnu.opt-gccold 0000644 0014172 0006025 00000001032 13303265233 021243 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.gnu.opt-gccold,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3 -m64 -std=gnu99
LDFLAGS = -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m64 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.linux.x86_64.gnu.dbg 0000644 0014172 0006025 00000001002 13303265233 017741 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.gnu.dbg,v 1.7 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -m64 -g $(GCCWARN) -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m64 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.darwin.x86.gnu.dbg 0000644 0014172 0006025 00000000675 13301553023 017567 0 ustar bzfschlo optimi CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -m32 -g -fident $(GCCWARN)
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m32 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS = -Bstatic -lgmp -lm
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.linux.x86_64.intel.dbg 0000644 0014172 0006025 00000000642 13301553023 020267 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.intel.dbg,v 1.4 2014/01/12 11:07:04 bzfkocht Exp $
CC = icc
CPPFLAGS += -DFREEMEM
CFLAGS = -g -fp-model precise -w2 -Wcheck \
-par_report0 -vec_report0 \
-wd111,171,279,981,1173,1419,1684
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
# -wd383,444,810
#ifeq ($(LINK),shared)
#LINK = normal
#endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.freebsd.x86_64.gnu.dbg 0000644 0014172 0006025 00000000425 13301553023 020217 0 ustar bzfschlo optimi #--- $Id: make.freebsd.x86_64.gnu.dbg,v 1.2 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -I/usr/local/include -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -g -fident -ftrapv $(GCCWARN)
LDFLAGS = -L/usr/local/lib -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/nmake.win.x86_64.msvc.opt 0000644 0014172 0006025 00000000207 13301553023 020003 0 ustar bzfschlo optimi CPPFLAGS = $(CPPFLAGS) /Dinline=_inline /DWIN64 /DNDEBUG
CFLAGS = $(CFLAGS) /W2 /wd4274 /Ox /nologo
LDFLAGS = $(LDFLAGS) /LTCG
zimpl-3.3.6/make/make.linux.x86_64.gnu.opt 0000644 0014172 0006025 00000001020 13303265236 020012 0 ustar bzfschlo optimi #--- $Id: make.linux.x86_64.gnu.opt,v 1.9 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3 -g -m64 -mtune=native -std=gnu99
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m64 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -static
#endif
zimpl-3.3.6/make/make.sunos.sparc.sun.opt 0000644 0014172 0006025 00000000366 13301553023 020214 0 ustar bzfschlo optimi #--- $Id: make.sunos.sparc.sun.opt,v 1.12 2014/01/12 11:07:04 bzfkocht Exp $
CC = cc
CPPFLAGS += -DNDEBUG -DNO_MSHELL -Dinline=""
CFLAGS = -fast -xprefetch=auto -xipo=2
LDFLAGS = -Bstatic -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.darwin.x86.intel.opt 0000644 0014172 0006025 00000000425 13301553023 020150 0 ustar bzfschlo optimi #--- $Id: make.darwin.x86.intel.opt,v 1.3 2014/01/12 11:07:04 bzfkocht Exp $
CC = icc
CPPFLAGS += -DNDEBUG -DNO_MSHELL
CFLAGS = -O3 -ip -fp-model precise -w1 -par_report0 -vec_report0 \
-wd1173
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.darwin.x86_64.gnu.dbg 0000644 0014172 0006025 00000001062 13301553023 020067 0 ustar bzfschlo optimi #--- $Id: make.darwin.x86_64.gnu.dbg,v 1.7 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -m64 -g -fident $(GCCWARN)
LDFLAGS = -lgmp -lm
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -m64 -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS = -Bstatic -lgmp -lm
#endif
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/make.cygwin.x86.gnu.opt 0000644 0014172 0006025 00000000402 13301553023 017635 0 ustar bzfschlo optimi #--- $Id: make.cygwin.x86.gnu.opt,v 1.9 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DWINDOWS -DNDEBUG -DNO_MSHELL -D__NO_MATH_INLINES
CFLAGS = -O3 -march=pentiumpro -g $(GCCWARN)
LDFLAGS = -lgmp -lm -static
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
zimpl-3.3.6/make/local/ 0000755 0014172 0006025 00000000000 13301553023 014557 5 ustar bzfschlo optimi zimpl-3.3.6/make/make.sunos.x86.gnu.dbg 0000644 0014172 0006025 00000000763 13301553023 017450 0 ustar bzfschlo optimi #--- $Id: make.sunos.x86.gnu.dbg,v 1.7 2014/01/12 11:07:04 bzfkocht Exp $
CPPFLAGS += -DFREEMEM -D__NO_MATH_INLINES
CFLAGS = -O0 -g -fident $(GCCWARN)
LDFLAGS = -lgmp -lm
ifeq ($(ZLIB),true)
LDFLAGS += -lz
endif
ifeq ($(LINK),shared)
#LIBRARY = $(LIBDIR)/lib$(LIBNAME).so
#LIBLINK = $(LIBDIR)/lib$(NAME).$(BASE).so
CFLAGS += -fPIC
#AR = gcc -shared -o # the trailing space is important
#ARFLAGS = $(LDFLAGS)
#RANLIB = true
endif
#ifeq ($(LINK),static)
LDFLAGS += -Bstatic
#endif
zimpl-3.3.6/src/ 0000755 0014172 0006025 00000000000 13303714344 013346 5 ustar bzfschlo optimi zimpl-3.3.6/src/project2.lnt 0000644 0014172 0006025 00000012445 13303714141 015616 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: project2.lnt */
/* Name....: PCLint+ Project Settings */
/* Author..: Thorsten Koch */
/* Copyright (C) 2001-2018 by Thorsten Koch */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// TK 29Jan2018
//-hook(pre_option, -cond('%[option]' == '-sem', -reject)) //# Fix Bug in pclint 1.0
-max_threads=8
-vt_depth=20
+fsc // strings are const
-A(C99)
-width(132,4)
-"format=%f:%l: %t %n: %m"
-ffc // Function takes Custody flag -> off
//-hFb^3
//
//-e636 // strong type
//-e632 // strong type
-e571 // cast leads to sign extention
-e750 // local MACRO not referenced
//
-esym(534,close,creat,fclose,fprintf,fputc,fflush,fsync,pclose,gzclose)
-esym(534,fputs,fscanf,fseek,fwrite,lseek,memcpy,memmove,memset)
-esym(534,printf,puts,scanf,sprintf,sscanf,strcat,strcpy)
-esym(534,strncat,strncpy,unlink,write,regerror)
//
-e592 // Non-literal format specifier used without arguments
-e749 // local enumeration constant not referenced
-e758 // Operator followed by operator is confusing
-e766 // Include of header file not used
-e788 // enum constant not used within defaulted switch
-e801 // Use of goto is deprecated
-e826 // Suspicious pointer-to-pointer conversion
-e834 // Operator followed by operator is confusing. Use parentheses
//
-strong(AzJzX,Tuple,Set,Str,vbool_cmp_operator,vbool_fixed_result)
-strong(AzJzX,IdxSet,Term,TermElem,ineq_type,Ineq,Local,ListElem,List)
-strong(AzJzX,ListElem,List,ListData,list_type)
-strong(AzJzX,stmt_type,Stmt,Prog,code_type,CodeNode)
-strong(AzJzX,RDef,RPar,MFP,rpar_type,RParVal)
-strong(AazJX,Bound)
-strong(AzJzX,bound_type)
-strong(AzJzX,Heap,heap_type,HeapData,heapCmp)
-strong(AizJzX,SetIter,setcheck_type,define_type,Define)
-strong(AzJzX,Var,var_type,VarState,var_class,Con,con_type,ConState,LpDirect,lp_type,lp_format,lp_type,lp_direct)
-strong(AzJzX,LpsHElem,lps_hash_type)
-strong(AzJzX,PSResult)
-strong(AzJzX,set_type,SetVTab,SetEmpty,SetPseudo,SetHead,SetList,SetRange,SetProd,SetMulti)
-strong(AzJzX,SetEmptyIter,SetPseudoIter,SetListIter,SetRangeIter,SetProdIter,SetMultiIter)
-strong(AzJzX,elem_type,Elem,ElemValue,ElemStore)
-strong(AzJzX,Entry,EntryValue,symbol_type,Symbol)
-strong(AzJzX,Pool,PoolElem)
-strong(AzJzX,Numb,NumbStore)
-strong(AzJzX,StrgFile,file_type)
-strong(AzJzX,hash_type,Hash,HElem,SetElemIdx)
-strong(AzJzX,HeapData,heap_data)
-strong(AcJX,Inst)
//-strong(AJXB,LintBool)
//
-esym(537,stdarg.h,sys/types.h) // repeated include file
-esym(534,stkchk_used_x) // ignore return value
-efile(413 428 537 613 661 676 685, src/mmlparse2.c)
-efile(717 732 734 744 746 774 825 845 2704, src/mmlparse2.c)
-efile(755, src/mmlparse2.h)
-esym(*, yyptr, yynerrs, yystate, yyerrstatus, yytokentype, yychar, yylen)
-esym(*, yyresult, yytype_int8, yytype_int16, yytop, yybottom, yyvsp, yyssp, yyvaluep)
-esym(2701, yylex, yyerror, yydebug,yy_flex_debug)
-efile(527 616 633 825, src/mmlscan.c)
-efile(534 527 537 539 574 676 702 712 714 716 717 725 732 737 744 765 773 774 775 835 845 891 893, src/mmlscan.c)
-esym(*, yyleng, yytext, yyset_extra, yyget_extra, flex_int8_t, flex_uint8_t, flex_uint32_t, yy_trans_info, yy_trans_info::yy_verify, yy_trans_info::yy_nxt)
-efile(663, src/numbgmp.c)
-esym(714 759 765, numb_div, numb_intdiv, numb_mod) // symbol not externally used
-esym(755, ZIMPL_VERSION)
-esym(755, mem_check_all, mem_hide, mem_maximum, mem_used)
-esym(755, stchk_display)
-e769 // global enumeration constant not referenced
-esym(818, iter_next, iter_reset) // parameter could be pointer to const
-esym(818, set_empty_get_tuple, set_pseudo_get_tuple) // parameter could be pointer to const
-efunc(2466,iter_next) // used even marked as unused
-esym(755,Min,stkchk_display) // global Macro not referenced
-esym(757,lps_readmps)
-esym(714 759 765, lps_delcon, lps_delvar, lps_flags, lps_getsos, lps_setbndname, lps_setcontype, lps_setprobname, lps_setrhsname, lps_setrngname, lps_setscale, lps_setvalue, lps_setvartype, lps_vartype) // not referenced, move to module, made static
-esym(759 765, lps_number, lps_getvar) // move to module, made static
-esym(714 759 765, code_set_child, code_value_bits, code_value_contype, code_value_size, code_value_varclass)
-esym(714 759 765, idxset_print)
-esym(714 759 765, i_bool_false, i_set_pseudo) // ???
-esym(759 765, list_print)
-esym(759 765, mio_add_strg_file, mio_gets)
-esym(768, set_empty::head, set_multi::head, set_prod::head, set_pseudo::head, set_range::head)
-esym(768, set_empty_iter::dummy)
-esym(714 759 765, gmp_print_mpq)
-esym(714 759 765, term_print)
-esym(714 759 765, zpl_read, zpl_read_with_args)
-esym(714 759 765, tuple_combine)
-esym(714 759 765, numb_tostr)
-esym(714 759 765, symbol_get_dim, symbol_get_numb, symbol_get_set, symbol_get_strg, symbol_get_var, symbol_has_entry, symbol_is_valid)
-esym(714 759 765, stkchk_display_x, stkchk_maxi, stkchk_start)
-esym(714 759 765, mono_mul_entry)
-esym(714 759 765, prog_is_valid)
//++dbool=LintBool
//++dtrue=((LintBool)1)
//++dfalse=((LintBool)0)
//-header(lint.h)
zimpl-3.3.6/src/WIN/ 0000755 0014172 0006025 00000000000 13303714141 013776 5 ustar bzfschlo optimi zimpl-3.3.6/src/WIN/getopt.h 0000644 0014172 0006025 00000015003 13303714141 015450 0 ustar bzfschlo optimi /* getopt.h */
/* Declarations for getopt.
Copyright (C) 1989-1994, 1996-1999, 2001 Free Software
Foundation, Inc. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute
it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software
Foundation; either version 2.1 of the License, or
(at your option) any later version.
The GNU C Library is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General
Public License along with the GNU C Library; if not, write
to the Free Software Foundation, Inc., 59 Temple Place,
Suite 330, Boston, MA 02111-1307 USA. */
#ifndef _GETOPT_H
#ifndef __need_getopt
# define _GETOPT_H 1
#endif
/* If __GNU_LIBRARY__ is not already defined, either we are being used
standalone, or this is the first header included in the source file.
If we are being used with glibc, we need to include , but
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
not defined, include , which will pull in for us
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
doesn't flood the namespace with stuff the way some other headers do.) */
#if !defined __GNU_LIBRARY__
# include
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
#ifndef __need_getopt
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
# if (defined __STDC__ && __STDC__) || defined __cplusplus
const char *name;
# else
char *name;
# endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
# define no_argument 0
# define required_argument 1
# define optional_argument 2
#endif /* need getopt */
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
Return the option character from OPTS just read. Return -1 when
there are no more options. For unrecognized options, or options
missing arguments, `optopt' is set to the option letter, and '?' is
returned.
The OPTS string is a list of characters which are recognized option
letters, optionally followed by colons, specifying that that letter
takes an argument, to be placed in `optarg'.
If a letter in OPTS is followed by two colons, its argument is
optional. This behavior is specific to the GNU `getopt'.
The argument `--' causes premature termination of argument
scanning, explicitly telling `getopt' that there are no more
options.
If OPTS begins with `--', then non-option arguments are treated as
arguments to the option '\0'. This behavior is specific to the GNU
`getopt'. */
#if (defined __STDC__ && __STDC__) || defined __cplusplus
# ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
# else /* not __GNU_LIBRARY__ */
extern int getopt ();
# endif /* __GNU_LIBRARY__ */
# ifndef __need_getopt
extern int getopt_long (int ___argc, char *const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind);
extern int getopt_long_only (int ___argc, char *const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int ___argc, char *const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
int __long_only);
# endif
#else /* not __STDC__ */
extern int getopt ();
# ifndef __need_getopt
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
# endif
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
/* Make sure we later can get all the definitions and declarations. */
#undef __need_getopt
#endif /* getopt.h */
zimpl-3.3.6/src/WIN/unistd.h 0000644 0014172 0006025 00000001030 13303714141 015447 0 ustar bzfschlo optimi #ifndef _UNISTD_H
#define _UNISTD_H
/* This file intended to serve as a drop-in replacement for
* unistd.h on Windows
* Please add functionality as neeeded
*/
#include
#include
#include /* getopt from: http://www.pwilson.net/sample.html. */
#ifdef __cplusplus
extern "C" {
#endif
#define srandom srand
#define random rand
#define W_OK 2
#define R_OK 4
#define access _access
#define ftruncate _chsize
#define ssize_t int
#ifdef __cplusplus
}
#endif
#endif /* unistd.h */
zimpl-3.3.6/src/WIN/getopt.c 0000644 0014172 0006025 00000116363 13303714141 015456 0 ustar bzfschlo optimi
/* Getopt for GNU.
NOTE: getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to drepper@gnu.org
before changing it!
Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* This tells Alpha OSF/1 not to define a getopt prototype in .
Ditto for AIX 3.2 and . */
#ifndef _NO_PROTO
# define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
# include
#endif
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
# ifndef const
# define const
# endif
#endif
#include
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
# include
# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
# define ELIDE_CODE
# endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
# include
# include
#endif /* GNU C library. */
#ifdef VMS
# include
# if HAVE_STRING_H - 0
# include
# endif
#endif
#ifndef _
/* This is for other GNU distributions with internationalized messages. */
# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
# include
# ifndef _
# define _(msgid) gettext (msgid)
# endif
# else
# define _(msgid) (msgid)
# endif
# if defined _LIBC && defined USE_IN_LIBIO
# include
# endif
#endif
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
As `getopt' works, it permutes the elements of ARGV so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable POSIXLY_CORRECT disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include "getopt.h"
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
/* 1003.2 says this must be 1 before any call. */
int optind = 1;
/* Formerly, initialization of getopt depended on optind==0, which
causes problems with re-calling getopt as programs generally don't
know that. */
int __getopt_initialized;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int opterr = 1;
/* Set to an option character which was unrecognized.
This must be initialized on some systems to avoid linking in the
system's own getopt implementation. */
int optopt = '?';
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters.
PERMUTE is the default. We permute the contents of ARGV as we scan,
so that eventually all the non-options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code 1.
Using `-' as the first character of the list of option characters
selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
/* Value of POSIXLY_CORRECT environment variable. */
static char *posixly_correct;
#ifdef __GNU_LIBRARY__
/* We want to avoid inclusion of string.h with non-GNU libraries
because there are many ways it can cause trouble.
On some systems, it contains special magic macros that don't work
in GCC. */
# include
# define my_index strchr
#else
# if HAVE_STRING_H || WIN32 || WIN64/* Pete Wilson mod 7/28/02 */
# include
# else
# include
# endif
/* Avoid depending on library functions or files
whose names are inconsistent. */
#ifndef getenv
extern char *getenv ();
#endif
static char *
my_index (
const char *str,
int chr)
{
while (*str)
{
if (*str == chr)
return (char *) str;
str++;
}
return 0;
}
/* If using GCC, we can safely declare strlen this way.
If not using GCC, it is ok not to declare it. */
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
# if (!defined __STDC__ || !__STDC__) && !defined strlen
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int strlen (const char *);
# endif /* not __STDC__ */
#endif /* __GNUC__ */
#endif /* not __GNU_LIBRARY__ */
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
#ifdef _LIBC
/* Stored original parameters.
XXX This is no good solution. We should rather copy the args so
that we can compare them later. But we must not use malloc(3). */
extern int __libc_argc;
extern char **__libc_argv;
/* Bash 2.0 gives us an environment variable containing flags
indicating ARGV elements that should not be considered arguments. */
# ifdef USE_NONOPTION_FLAGS
/* Defined in getopt_init.c */
extern char *__getopt_nonoption_flags;
static int nonoption_flags_max_len;
static int nonoption_flags_len;
# endif
# ifdef USE_NONOPTION_FLAGS
# define SWAP_FLAGS(ch1, ch2) \
if (nonoption_flags_len > 0) \
{ \
char __tmp = __getopt_nonoption_flags[ch1]; \
__getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
__getopt_nonoption_flags[ch2] = __tmp; \
}
# else
# define SWAP_FLAGS(ch1, ch2)
# endif
#else /* !_LIBC */
# define SWAP_FLAGS(ch1, ch2)
#endif /* _LIBC */
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
#if defined __STDC__ && __STDC__
static void exchange (char **);
#endif
static void
exchange (
char **argv)
{
int bottom = first_nonopt;
int middle = last_nonopt;
int top = optind;
char *tem;
/* Exchange the shorter segment with the far end of the longer segment.
That puts the shorter segment into the right place.
It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */
#if defined _LIBC && defined USE_NONOPTION_FLAGS
/* First make sure the handling of the `__getopt_nonoption_flags'
string can work normally. Our top argument must be in the range
of the string. */
if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
{
/* We must extend the array. The user plays games with us and
presents new arguments. */
char *new_str = malloc (top + 1);
if (new_str == NULL)
nonoption_flags_len = nonoption_flags_max_len = 0;
else
{
memset (__mempcpy (new_str, __getopt_nonoption_flags,
nonoption_flags_max_len),
'\0', top + 1 - nonoption_flags_max_len);
nonoption_flags_max_len = top + 1;
__getopt_nonoption_flags = new_str;
}
}
#endif
while (top > middle && middle > bottom)
{
if (top - middle > middle - bottom)
{
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
}
else
{
/* Top segment is the short one. */
int len = top - middle;
register int i;
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
SWAP_FLAGS (bottom + i, middle + i);
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
}
}
/* Update records for the slots the non-options now occupy. */
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
/* Initialize the internal data when the first call is made. */
#if defined __STDC__ && __STDC__
static const char *_getopt_initialize (int, char *const *, const char *);
#endif
static const char *
_getopt_initialize (
int argc,
char *const *argv,
const char *optstring)
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt = last_nonopt = optind;
nextchar = NULL;
posixly_correct = getenv ("POSIXLY_CORRECT");
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (posixly_correct != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
#if defined _LIBC && defined USE_NONOPTION_FLAGS
if (posixly_correct == NULL
&& argc == __libc_argc && argv == __libc_argv)
{
if (nonoption_flags_max_len == 0)
{
if (__getopt_nonoption_flags == NULL
|| __getopt_nonoption_flags[0] == '\0')
nonoption_flags_max_len = -1;
else
{
const char *orig_str = __getopt_nonoption_flags;
int len = nonoption_flags_max_len = strlen (orig_str);
if (nonoption_flags_max_len < argc)
nonoption_flags_max_len = argc;
__getopt_nonoption_flags =
(char *) malloc (nonoption_flags_max_len);
if (__getopt_nonoption_flags == NULL)
nonoption_flags_max_len = -1;
else
memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
'\0', nonoption_flags_max_len - len);
}
}
nonoption_flags_len = nonoption_flags_max_len;
}
else
nonoption_flags_len = 0;
#endif
return optstring;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns -1.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg', otherwise `optarg' is set to zero.
If OPTSTRING starts with `-' or `+', it requests different methods of
handling the non-option ARGV-elements.
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
Long-named options begin with `--' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
When `getopt' finds a long-named option, it returns 0 if that option's
`flag' field is nonzero, the value of the option's `val' field
if the `flag' field is zero.
The elements of ARGV aren't really const, because we permute them.
But we pretend they're const in the prototype to be compatible
with other systems.
LONGOPTS is a vector of `struct option' terminated by an
element containing a name which is zero.
LONGIND returns the index in LONGOPT of the long-named option found.
It is only valid when a long-named option has been found by the most
recent call.
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
int
_getopt_internal (
int argc,
char *const *argv,
const char *optstring,
const struct option *longopts,
int *longind,
int long_only)
{
int print_errors = opterr;
if (optstring[0] == ':')
print_errors = 0;
if (argc < 1)
return -1;
optarg = NULL;
if (optind == 0 || !__getopt_initialized)
{
if (optind == 0)
optind = 1; /* Don't scan ARGV[0], the program name. */
optstring = _getopt_initialize (argc, argv, optstring);
__getopt_initialized = 1;
}
/* Test whether ARGV[optind] points to a non-option argument.
Either it does not have option syntax, or there is an environment flag
from the shell indicating it is not an option. The later information
is only used when the used in the GNU libc. */
#if defined _LIBC && defined USE_NONOPTION_FLAGS
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|| (optind < nonoption_flags_len \
&& __getopt_nonoption_flags[optind] == '1'))
#else
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
#endif
if (nextchar == NULL || *nextchar == '\0')
{
/* Advance to the next ARGV-element. */
/* Give FIRST_NONOPT and LAST_NONOPT rational values if OPTIND has been
moved back by the user (who may also have changed the arguments). */
if (last_nonopt > optind)
last_nonopt = optind;
if (first_nonopt > optind)
first_nonopt = optind;
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (last_nonopt != optind)
first_nonopt = optind;
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc && NONOPTION_P)
optind++;
last_nonopt = optind;
}
/* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optind = first_nonopt;
return -1;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if (NONOPTION_P)
{
if (ordering == REQUIRE_ORDER)
return -1;
optarg = argv[optind++];
return 1;
}
/* We have found another option-ARGV-element.
Skip the initial punctuation. */
nextchar = (argv[optind] + 1
+ (longopts != NULL && argv[optind][1] == '-'));
}
/* Decode the current option-ARGV-element. */
/* Check whether the ARGV-element is a long option.
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
This distinction seems to be the most useful approach. */
if (longopts != NULL
&& (argv[optind][1] == '-'
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
{
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = -1;
int option_index;
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((unsigned int) (nameend - nextchar)
== (unsigned int) strlen (p->name))
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else if (long_only
|| pfound->has_arg != p->has_arg
|| pfound->flag != p->flag
|| pfound->val != p->val)
/* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (print_errors)
{
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[optind]);
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#else
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[optind]);
#endif
}
nextchar += strlen (nextchar);
optind++;
optopt = 0;
return '?';
}
if (pfound != NULL)
{
option_index = indfound;
optind++;
if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
if (print_errors)
{
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
#endif
if (argv[optind - 1][1] == '-')
{
/* --option */
#if defined _LIBC && defined USE_IN_LIBIO
__asprintf (&buf, _("\
%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
#else
fprintf (stderr, _("\
%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
#endif
}
else
{
/* +option or -option */
#if defined _LIBC && defined USE_IN_LIBIO
__asprintf (&buf, _("\
%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[optind - 1][0],
pfound->name);
#else
fprintf (stderr, _("\
%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[optind - 1][0], pfound->name);
#endif
}
#if defined _LIBC && defined USE_IN_LIBIO
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#endif
}
nextchar += strlen (nextchar);
optopt = pfound->val;
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
optarg = argv[optind++];
else
{
if (print_errors)
{
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
__asprintf (&buf,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#else
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
#endif
}
nextchar += strlen (nextchar);
optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
/* Can't find it as a long option. If this is not getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if (!long_only || argv[optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL)
{
if (print_errors)
{
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
#endif
if (argv[optind][1] == '-')
{
/* --option */
#if defined _LIBC && defined USE_IN_LIBIO
__asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
#else
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
#endif
}
else
{
/* +option or -option */
#if defined _LIBC && defined USE_IN_LIBIO
__asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[optind][0], nextchar);
#else
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[optind][0], nextchar);
#endif
}
#if defined _LIBC && defined USE_IN_LIBIO
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#endif
}
nextchar = (char *) "";
optind++;
optopt = 0;
return '?';
}
}
/* Look at and handle the next short option-character. */
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == '\0')
++optind;
if (temp == NULL || c == ':')
{
if (print_errors)
{
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
#endif
if (posixly_correct)
{
/* 1003.2 specifies the format of this message. */
#if defined _LIBC && defined USE_IN_LIBIO
__asprintf (&buf, _("%s: illegal option -- %c\n"),
argv[0], c);
#else
fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
#endif
}
else
{
#if defined _LIBC && defined USE_IN_LIBIO
__asprintf (&buf, _("%s: invalid option -- %c\n"),
argv[0], c);
#else
fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
#endif
}
#if defined _LIBC && defined USE_IN_LIBIO
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#endif
}
optopt = c;
return '?';
}
/* Convenience. Treat POSIX -W foo same as long option --foo */
if (temp[0] == 'W' && temp[1] == ';')
{
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = 0;
int option_index;
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (print_errors)
{
/* 1003.2 specifies the format of this message. */
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
__asprintf (&buf, _("%s: option requires an argument -- %c\n"),
argv[0], c);
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#else
fprintf (stderr, _("%s: option requires an argument -- %c\n"),
argv[0], c);
#endif
}
optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
return c;
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
/* optarg is now the argument, see if it's in the
table of longopts. */
for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((unsigned int) (nameend - nextchar) == strlen (p->name))
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
/* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (print_errors)
{
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
argv[0], argv[optind]);
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#else
fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
argv[0], argv[optind]);
#endif
}
nextchar += strlen (nextchar);
optind++;
return '?';
}
if (pfound != NULL)
{
option_index = indfound;
if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
if (print_errors)
{
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
__asprintf (&buf, _("\
%s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name);
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#else
fprintf (stderr, _("\
%s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name);
#endif
}
nextchar += strlen (nextchar);
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
optarg = argv[optind++];
else
{
if (print_errors)
{
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
__asprintf (&buf, _("\
%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#else
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
#endif
}
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
nextchar = NULL;
return 'W'; /* Let the application handle it. */
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != '\0')
{
optarg = nextchar;
optind++;
}
else
optarg = NULL;
nextchar = NULL;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (print_errors)
{
/* 1003.2 specifies the format of this message. */
#if defined _LIBC && defined USE_IN_LIBIO
char *buf;
__asprintf (&buf,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
if (_IO_fwide (stderr, 0) > 0)
__fwprintf (stderr, L"%s", buf);
else
fputs (buf, stderr);
free (buf);
#else
fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
#endif
}
optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
nextchar = NULL;
}
}
return c;
}
}
int
getopt (
int argc,
char *const *argv,
const char *optstring)
{
return _getopt_internal (argc, argv, optstring,
(const struct option *) 0,
(int *) 0,
0);
}
#endif /* Not ELIDE_CODE. */
/* Compile with -DTEST to make an executable for use in testing
the above definition of `getopt'. */
/* #define TEST */ /* Pete Wilson mod 7/28/02 */
#ifdef TEST
#ifndef exit /* Pete Wilson mod 7/28/02 */
int exit(int); /* Pete Wilson mod 7/28/02 */
#endif /* Pete Wilson mod 7/28/02 */
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
c = getopt (argc, argv, "abc:d:0123456789");
if (c == -1)
break;
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */
zimpl-3.3.6/src/zimpl/ 0000755 0014172 0006025 00000000000 13317100345 014474 5 ustar bzfschlo optimi zimpl-3.3.6/src/zimpl/stmt.c 0000644 0014172 0006025 00000013453 13304236715 015644 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: stmt.c */
/* Name....: Statement Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include "zimpl/lint.h"
#include
#include "zimpl/mshell.h"
#include "zimpl/stkchk.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/entry.h"
#include "zimpl/idxset.h"
#include "zimpl/rdefpar.h"
#include "zimpl/bound.h"
#include "zimpl/define.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/list.h"
#include "zimpl/local.h"
#include "zimpl/code.h"
#include "zimpl/inst.h"
#include "zimpl/stmt.h"
#define STMT_SID 0x53746d74
struct statement
{
SID
StmtType type;
const char* filename;
int lineno;
const char* text;
CodeNode* node;
};
#define MAX_WARNINGS 1000
static int warning_count[MAX_WARNINGS];
static void activate_warnings(void)
{
int i;
for(i = 0; i < MAX_WARNINGS; i++)
warning_count[i] = 0;
}
static void show_suppressed_warnings(void)
{
if (verbose > VERB_QUIET && verbose < VERB_CHATTER)
{
int i;
for(i = 0; i < MAX_WARNINGS; i++)
if (warning_count[i] > 1)
fprintf(stderr, "--- Warning %3d: suppressed %d further message(s)\n",
i, warning_count[i] - 1);
}
}
bool stmt_trigger_warning(int no)
{
bool ret;
assert(no >= 0);
assert(no < MAX_WARNINGS);
ret = (warning_count[no] == 0);
warning_count[no]++;
if (verbose >= VERB_CHATTER)
ret = true;
if (verbose <= VERB_QUIET)
ret = false;
return ret;
}
Stmt* stmt_new(
StmtType type,
const char* filename,
int lineno,
const char* text)
{
Stmt* stmt = calloc(1, sizeof(*stmt));;
assert(filename != NULL);
assert(text != NULL);
assert(stmt != NULL);
assert(lineno > 0);
stmt->type = type;
stmt->filename = strdup(filename);
stmt->lineno = lineno;
stmt->text = strdup(text);
stmt->node = NULL;
SID_set(stmt, STMT_SID);
assert(stmt_is_valid(stmt));
return stmt;
}
void stmt_free(Stmt* stmt)
{
assert(stmt_is_valid(stmt));
SID_del(stmt);
if (stmt->node != NULL)
code_free(stmt->node);
free((void*)stmt->filename);
free((void*)stmt->text);
free(stmt);
}
bool stmt_is_valid(const Stmt* stmt)
{
return ((stmt != NULL)
&& SID_ok(stmt, STMT_SID)
&& (stmt->filename != NULL)
&& (stmt->lineno > 0)
&& (stmt->text != NULL));
}
const char* stmt_get_filename(const Stmt* stmt)
{
assert(stmt_is_valid(stmt));
return stmt->filename;
}
int stmt_get_lineno(const Stmt* stmt)
{
assert(stmt_is_valid(stmt));
return stmt->lineno;
}
const char* stmt_get_text(const Stmt* stmt)
{
assert(stmt_is_valid(stmt));
return stmt->text;
}
void stmt_parse(Stmt* stmt)
{
Trace("stmt_parse");
assert(stmt_is_valid(stmt));
if (verbose >= VERB_VERBOSE)
printf("Parsing %s %d\n", stmt->filename, stmt->lineno);
parse_stmt(stmt);
stmt->node = code_get_root();
}
void stmt_execute(const Stmt* stmt)
{
unsigned int inst_count = code_get_inst_count();
Trace("stmt_execute");
assert(stmt_is_valid(stmt));
if (verbose >= VERB_VERBOSE)
printf("Executing %s %d\n", stmt->filename, stmt->lineno);
activate_warnings();
(void)code_prune_tree(stmt->node);
/* ??? I don't think this can happen without a parse error first.
*/
if (code_get_type(code_eval(stmt->node)) != CODE_VOID)
{ /* ^^^^^^^^^^^^^^^^^^^^ */
fprintf(stderr, "*** Error 169: Execute must return void element\n");
zpl_exit(EXIT_FAILURE);
}
show_suppressed_warnings();
if (verbose >= VERB_CHATTER)
{
printf("Instructions evaluated: %u\n", code_get_inst_count() - inst_count);
stkchk_maximum(stdout);
}
}
void stmt_print(FILE* fp, const Stmt* stmt)
{
static const char* const type_name[] =
{
"Unknown", "Set", "Param", "Var", "Min", "Max", "Cons", "Define", "Print", "SOS"
};
assert(stmt_is_valid(stmt));
/* Lint weiss hier dass das assert immer erfuellt sein muss.
* aber wir wollen es trotzdem.
*/
assert((unsigned int)stmt->type
< (sizeof(type_name) / sizeof(type_name[0]))); /*lint !e650 */
fprintf(fp, "%s %04d %-7s [%s]\n",
stmt->filename,
stmt->lineno,
type_name[(int)stmt->type],
stmt->text);
}
zimpl-3.3.6/src/zimpl/zimpllib.c 0000644 0014172 0006025 00000023473 13304236715 016502 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: zimpllib.c */
/* Name....: ZIMPL Library Interface */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2005-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include
#include "zimpl/mshell.h"
#include "zimpl/stkchk.h"
#include "zimpl/blkmem.h"
#include "zimpl/random.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/define.h"
#include "zimpl/bound.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/stmt.h"
#include "zimpl/local.h"
#include "zimpl/list.h"
#include "zimpl/entry.h"
#include "zimpl/xlpglue.h"
#include "zimpl/prog.h"
#include "zimpl/metaio.h"
#include "zimpl/strstore.h"
#include "zimpl/zimpllib.h"
extern int yydebug;
extern int yy_flex_debug;
int verbose = VERB_QUIET;
static jmp_buf zpl_read_env;
static bool is_longjmp_ok = false;
void zpl_print_banner(FILE* fp, bool with_license)
{
const char* const banner =
"****************************************************\n" \
"* Zuse Institute Mathematical Programming Language *\n" \
"* Release %-5s Copyright (C)2018 by Thorsten Koch *\n" \
"****************************************************\n";
const char* const license =
"* This is free software and you are welcome to *\n" \
"* redistribute it under certain conditions *\n" \
"* ZIMPL comes with ABSOLUTELY NO WARRANTY *\n" \
"****************************************************\n";
if (verbose >= VERB_NORMAL)
{
fprintf(fp, banner, VERSION);
if (with_license || verbose > VERB_NORMAL)
fprintf(fp, "%s", license);
fputc('\n', fp);
}
}
void zpl_exit(int retval)
{
if (is_longjmp_ok)
longjmp(zpl_read_env, retval);
#if defined(NDEBUG) || defined(COVERAGE)
exit(retval);
#else
abort(); /* to get a stack trace */
#endif
}
static bool is_valid_identifier(const char* s)
{
assert(s != NULL);
/* Identifiers start with a letter or a '_'
*/
if (!isalpha(*s) || *s == '_')
return false;
/* Then letters, digits or '_' can follow.
*/
while(isalnum(*++s) || *s == '_')
;
return *s == '\0';
}
void zpl_var_print(FILE* fp, const Var* var)
{
const char* name = xlp_getvarname(prog_get_lp(), var);
VarClass class = xlp_getclass(prog_get_lp(), var);
Bound* lower = xlp_getlower(prog_get_lp(), var);
Bound* upper = xlp_getupper(prog_get_lp(), var);
fprintf(fp, "\"%s\" ", name);
switch(class)
{
case VAR_CON :
fprintf(fp, "real [");
break;
case VAR_IMP :
fprintf(fp, "implicit integer [");
break;
case VAR_INT :
fprintf(fp, "integer [");
break;
default :
abort();
}
bound_print(fp, lower);
fprintf(fp, ",");
bound_print(fp, upper);
fprintf(fp, "] ");
bound_free(upper);
bound_free(lower);
}
void zpl_add_parameter(const char* def)
{
const char* warning =
"--- Warning 175: Illegal syntax for command line define \"%s\" -- ignored\n";
Set* set;
Symbol* sym;
Tuple* tuple;
Entry* entry;
char* name;
char* value;
assert(def != NULL);
name = strdup(def);
value = strchr(name, '=');
if (value == NULL)
{
fprintf(stderr, warning, def);
free(name);
return;
}
*value = '\0';
value++;
if (strlen(name) == 0 || strlen(value) == 0 || !is_valid_identifier(name))
{
if (verbose > VERB_QUIET)
fprintf(stderr, warning, def);
free(name);
return;
}
set = set_pseudo_new();
sym = symbol_new(str_new(name), SYM_ERR, set, 1, ENTRY_NULL);
tuple = tuple_new(0);
if (!numb_is_number(value))
entry = entry_new_strg(tuple, str_new(value));
else
{
Numb* numb = numb_new_ascii(value);
entry = entry_new_numb(tuple, numb);
numb_free(numb);
}
symbol_add_entry(sym, entry);
tuple_free(tuple);
set_free(set);
free(name);
}
bool zpl_read(const char* filename, bool with_management, void* user_data)
{
Prog* prog = NULL;
void* lp = NULL;
bool ret = false;
stkchk_init();
yydebug = 0;
yy_flex_debug = 0;
zpl_print_banner(stdout, false);
blk_init();
str_init();
rand_init(13021967UL);
numb_init(with_management);
elem_init();
set_init();
mio_init();
interns_init();
local_init();
if (0 == setjmp(zpl_read_env))
{
Set* set;
is_longjmp_ok = true;
set = set_pseudo_new();
(void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL);
set_free(set);
prog = prog_new();
prog_load(prog, NULL, filename);
if (prog_is_empty(prog))
fprintf(stderr, "*** Error 168: No program statements to execute\n");
else
{
if (verbose >= VERB_DEBUG)
prog_print(stderr, prog);
lp = xlp_alloc(filename, false, user_data);
prog_execute(prog, lp);
ret = true;
}
}
is_longjmp_ok = false;
if (lp != NULL)
xlp_free(lp);
if (prog != NULL)
prog_free(prog);
local_exit();
interns_exit();
mio_exit();
symbol_exit();
define_exit();
set_exit();
elem_exit();
numb_exit();
str_exit();
blk_exit();
return ret;
}
bool zpl_read_with_args(char** argv, int argc, bool with_management, void* user_data)
{
const char* options = "D:mP:s:v:";
unsigned long seed = 13021967UL;
char** param_table;
int param_count = 0;
int c;
int i;
Prog* prog = NULL;
void* lp = NULL;
bool ret = false;
char* inppipe = NULL;
bool use_startval = false;
stkchk_init();
yydebug = 0;
yy_flex_debug = 0;
param_table = malloc(sizeof(*param_table));
zpl_print_banner(stdout, false);
/* getopt might be called more than once
*/
optind = 1;
while((c = getopt(argc, argv, options)) != -1)
{
switch(c)
{
case 'D' :
param_table =
realloc(param_table, ((unsigned int)param_count + 1) * sizeof(*param_table));
param_table[param_count] = strdup(optarg);
if (verbose >= VERB_DEBUG)
printf("Parameter %d [%s]\n", param_count, param_table[param_count]);
param_count++;
break;
case 'm' :
use_startval = true;
break;
case 'P' :
inppipe = strdup(optarg);
break;
case 's' :
seed = (unsigned long)atol(optarg);
break;
case 'v' :
verbose = atoi(optarg);
break;
case '?':
fprintf(stderr, "Unknown option '%c'\n", c);
return false;
default :
abort();
}
}
if ((argc - optind) < 1)
{
fprintf(stderr, "Filename missing\n");
free(param_table);
return false;
}
blk_init();
str_init();
rand_init(seed);
numb_init(with_management);
elem_init();
set_init();
mio_init();
interns_init();
local_init();
if (0 == setjmp( zpl_read_env))
{
Set* set;
is_longjmp_ok = true;
/* Make symbol to hold entries of internal variables
*/
set = set_pseudo_new();
(void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL);
set_free(set);
/* Now store the param defines
*/
for(i = 0; i < param_count; i++)
zpl_add_parameter(param_table[i]);
prog = prog_new();
for(i = optind; i < argc; i++)
prog_load(prog, inppipe, argv[i]);
if (prog_is_empty(prog))
fprintf(stderr, "*** Error 168: No program statements to execute\n");
else
{
if (verbose >= VERB_DEBUG)
prog_print(stderr, prog);
lp = xlp_alloc(argv[optind], use_startval, user_data);
prog_execute(prog, lp);
ret = true;
}
}
is_longjmp_ok = false;
if (lp != NULL)
xlp_free(lp);
/* Now clean up.
*/
if (inppipe != NULL)
free(inppipe);
for(i = 0; i < param_count; i++)
free(param_table[i]);
free(param_table);
if (prog != NULL)
prog_free(prog);
local_exit();
interns_exit();
mio_exit();
symbol_exit();
define_exit();
set_exit();
elem_exit();
numb_exit();
str_exit();
blk_exit();
return ret;
}
zimpl-3.3.6/src/zimpl/set4.c 0000644 0014172 0006025 00000041245 13304236715 015534 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: set4.c */
/* Name....: Set Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/list.h"
#include "zimpl/hash.h"
#include "zimpl/stmt.h"
#include "zimpl/set.h"
#include "zimpl/entry.h"
#include "zimpl/set4.h"
#define TEST_DUBLICATE 0
#define SET_SID 0x5365745f
#ifndef NDEBUG
static
#endif
SetVTab* set_vtab_global = NULL;
void set_init()
{
assert(set_vtab_global == NULL);
set_vtab_global = calloc((size_t)SET_TYPES, sizeof(*set_vtab_global));
assert(set_vtab_global != NULL);
set_empty_init(set_vtab_global);
set_pseudo_init(set_vtab_global);
set_list_init(set_vtab_global);
set_range_init(set_vtab_global);
set_prod_init(set_vtab_global);
set_multi_init(set_vtab_global);
#if 0
set_union_init(set_vtab_global);
set_inter_init(set_vtab_global);
set_minus_init(set_vtab_global);
set_sdiff_init(set_vtab_global);
#endif
}
void set_exit()
{
assert(set_vtab_global != NULL);
free(set_vtab_global);
set_vtab_global = NULL;
}
Set* set_new_from_list(const List* list, SetCheckType check)
{
ListElem* le = NULL;
Set* set = NULL;
assert(list_is_valid(list));
assert(list_get_elems(list) > 0);
if (list_is_elemlist(list))
set = set_list_new_from_elems(list, check);
else if (list_is_tuplelist(list))
{
int dim = tuple_get_dim(list_get_tuple(list, &le));
if (dim == 1)
set = set_list_new_from_tuples(list, check);
else
set = set_multi_new_from_list(list, check);
}
else
{
assert(list_is_entrylist(list));
int dim = tuple_get_dim(entry_get_tuple(list_get_entry(list, &le)));
if (dim == 1)
set = set_list_new_from_entries(list, check);
else
set = set_multi_new_from_list(list, check);
}
assert(set_is_valid(set));
return set;
}
void set_free(Set* set)
{
set_vtab_global[set->head.type].set_free(set);
}
bool set_is_valid(const Set* set)
{
return set != NULL && set_vtab_global[set->head.type].set_is_valid(set);
}
Set* set_copy(const Set* set)
{
return set_vtab_global[set->head.type].set_copy(set);
}
inline SetIterIdx set_lookup_idx(const Set* set, const Tuple* tuple, int offset)
{
return set_vtab_global[set->head.type].set_lookup_idx(set, tuple, offset);
}
bool set_lookup(const Set* set, const Tuple* tuple)
{
if (set->head.dim != tuple_get_dim(tuple))
return false;
return set_vtab_global[set->head.type].set_lookup_idx(set, tuple, 0) >= 0;
}
inline void set_get_tuple_intern(const Set* set, SetIterIdx idx, Tuple* tuple, int offset)
{
set_vtab_global[set->head.type].set_get_tuple(set, idx, tuple, offset);
}
Tuple* set_get_tuple(const Set* set, SetIterIdx idx)
{
Tuple* tuple;
tuple = tuple_new(set->head.dim);
assert(set_is_valid(set));
assert(idx >= 0);
assert(idx < set->head.members);
set_get_tuple_intern(set, idx, tuple, 0);
return tuple;
}
inline SetIter* set_iter_init_intern(const Set* set, const Tuple* pattern, int offset)
{
return set_vtab_global[set->head.type].iter_init(set, pattern, offset);
}
SetIter* set_iter_init(const Set* set, const Tuple* pattern)
{
return set_iter_init_intern(set, pattern, 0);
}
inline bool set_iter_next_intern(SetIter* iter, const Set* set, Tuple* tuple, int offset)
{
return set_vtab_global[set->head.type].iter_next(iter, set, tuple, offset);
}
Tuple* set_iter_next(SetIter* iter, const Set* set)
{
Tuple* tuple;
tuple = tuple_new(set->head.dim);
if (set_iter_next_intern(iter, set, tuple, 0))
return tuple;
tuple_free(tuple);
return NULL;
}
inline void set_iter_exit_intern(SetIter* iter, const Set* set)
{
set_vtab_global[set->head.type].iter_exit(iter, set);
}
void set_iter_exit(SetIter* iter, const Set* set)
{
set_iter_exit_intern(iter, set);
}
inline void set_iter_reset_intern(SetIter* iter, const Set* set)
{
set_vtab_global[set->head.type].iter_reset(iter, set);
}
int set_get_dim(const Set* set)
{
assert(set_is_valid(set));
return set->head.dim;
}
int set_get_members(const Set* set)
{
assert(set_is_valid(set));
return set->head.members;
}
void set_print(FILE* fp, const Set* set)
{
assert(fp != NULL);
assert(set_is_valid(set));
switch(set->head.type)
{
case SET_EMPTY :
fprintf(fp, "Empty: ");
break;
case SET_PSEUDO :
fprintf(fp, "Pseudo: ");
break;
case SET_LIST :
fprintf(fp, "List: ");
break;
case SET_RANGE :
fprintf(fp, "Range: ");
break;
case SET_PROD :
fprintf(fp, "Product: ");
break;
case SET_MULTI :
fprintf(fp, "Multi: ");
break;
default :
abort();
}
fprintf(fp, "|%d|", set->head.dim);
fprintf(fp, "{");
SetIter* iter = set_iter_init(set, NULL);
Tuple* tuple;
bool first = true;
while(NULL != (tuple = set_iter_next(iter, set)))
{
if (first)
first = false;
else
fprintf(fp, ",");
tuple_print(fp, tuple);
tuple_free(tuple);
}
set_iter_exit(iter, set);
fprintf(fp, "}");
}
/* In A or in B */
Set* set_union(const Set* set_a, const Set* set_b)
{
Set* set;
SetIter* iter;
List* list = NULL;
Tuple* tuple;
assert(set_is_valid(set_a));
assert(set_is_valid(set_b));
assert(set_a->head.dim == set_b->head.dim
|| set_a->head.type == SET_EMPTY
|| set_b->head.type == SET_EMPTY);
iter = set_iter_init(set_a, NULL);
while(NULL != (tuple = set_iter_next(iter, set_a)))
{
if (list == NULL)
list = list_new_tuple(tuple);
else
list_add_tuple(list, tuple);
tuple_free(tuple);
}
set_iter_exit(iter, set_a);
iter = set_iter_init(set_b, NULL);
while(NULL != (tuple = set_iter_next(iter, set_b)))
{
if (!set_lookup(set_a, tuple))
{
if (list == NULL)
list = list_new_tuple(tuple);
else
list_add_tuple(list, tuple);
}
tuple_free(tuple);
}
set_iter_exit(iter, set_b);
if (list == NULL)
{
assert(set_get_members(set_a) + set_get_members(set_b) == 0);
set = set_empty_new(
set_a->head.type == SET_EMPTY ? set_b->head.dim : set_a->head.dim);
}
else
{
set = set_new_from_list(list, SET_CHECK_NONE);
assert(set_get_members(set) <= set_get_members(set_a) + set_get_members(set_b));
list_free(list);
}
return set;
}
/* In A and in B */
Set* set_inter(const Set* set_a, const Set* set_b)
{
Set* set;
SetIter* iter;
List* list = NULL;
Tuple* tuple;
assert(set_is_valid(set_a));
assert(set_is_valid(set_b));
assert(set_a->head.dim == set_b->head.dim
|| set_a->head.type == SET_EMPTY
|| set_b->head.type == SET_EMPTY);
iter = set_iter_init(set_a, NULL);
while(NULL != (tuple = set_iter_next(iter, set_a)))
{
if (set_lookup(set_b, tuple))
{
if (list == NULL)
list = list_new_tuple(tuple);
else
list_add_tuple(list, tuple);
}
tuple_free(tuple);
}
set_iter_exit(iter, set_a);
if (list == NULL)
set = set_empty_new(
set_a->head.type == SET_EMPTY ? set_b->head.dim : set_a->head.dim);
else
{
set = set_new_from_list(list, SET_CHECK_NONE);
assert(set_get_members(set) <= set_get_members(set_a) + set_get_members(set_b));
list_free(list);
}
return set;
}
/* In A but not in B */
Set* set_minus(const Set* set_a, const Set* set_b)
{
Set* set;
SetIter* iter;
List* list = NULL;
Tuple* tuple;
assert(set_is_valid(set_a));
assert(set_is_valid(set_b));
assert(set_a->head.dim == set_b->head.dim
|| set_a->head.type == SET_EMPTY
|| set_b->head.type == SET_EMPTY);
iter = set_iter_init(set_a, NULL);
while(NULL != (tuple = set_iter_next(iter, set_a)))
{
if (!set_lookup(set_b, tuple))
{
if (list == NULL)
list = list_new_tuple(tuple);
else
list_add_tuple(list, tuple);
}
tuple_free(tuple);
}
set_iter_exit(iter, set_a);
if (list == NULL)
{
assert(set_is_subseteq(set_a, set_b));
set = set_empty_new(
set_a->head.type == SET_EMPTY ? set_b->head.dim : set_a->head.dim);
}
else
{
set = set_new_from_list(list, SET_CHECK_NONE);
assert(set_get_members(set) <= set_get_members(set_a));
list_free(list);
}
return set;
}
/* In A and not in B or in B and not in A (Symetric difference) */
Set* set_sdiff(const Set* set_a, const Set* set_b)
{
Set* set;
SetIter* iter;
List* list = NULL;
Tuple* tuple;
assert(set_is_valid(set_a));
assert(set_is_valid(set_b));
assert(set_a->head.dim == set_b->head.dim
|| set_a->head.type == SET_EMPTY
|| set_b->head.type == SET_EMPTY);
iter = set_iter_init(set_a, NULL);
while(NULL != (tuple = set_iter_next(iter, set_a)))
{
if (!set_lookup(set_b, tuple))
{
if (list == NULL)
list = list_new_tuple(tuple);
else
list_add_tuple(list, tuple);
}
tuple_free(tuple);
}
set_iter_exit(iter, set_a);
iter = set_iter_init(set_b, NULL);
while(NULL != (tuple = set_iter_next(iter, set_b)))
{
if (!set_lookup(set_a, tuple))
{
if (list == NULL)
list = list_new_tuple(tuple);
else
list_add_tuple(list, tuple);
}
tuple_free(tuple);
}
set_iter_exit(iter, set_b);
if (list == NULL)
{
assert(set_is_equal(set_a, set_b));
set = set_empty_new(
set_a->head.type == SET_EMPTY ? set_b->head.dim : set_a->head.dim);
}
else
{
set = set_new_from_list(list, SET_CHECK_NONE);
assert(set_get_members(set) <= set_get_members(set_a) + set_get_members(set_b));
list_free(list);
}
return set;
}
/* project set_a to a new set, using the elements index in the tuple.
*/
Set* set_proj(const Set* set, const Tuple* pattern)
{
Tuple* tuple;
Tuple* new_tuple;
SetIter* iter;
List* list = NULL;
int i;
int dim;
int* idx;
Set* new_set;
assert(set_is_valid(set));
assert(tuple_is_valid(pattern));
dim = tuple_get_dim(pattern);
idx = malloc(sizeof(*idx) * (size_t)dim);
assert(idx != NULL);
for(i = 0; i < dim; i++)
{
assert(numb_is_int(elem_get_numb(tuple_get_elem(pattern, i))));
idx[i] = numb_toint(elem_get_numb(tuple_get_elem(pattern, i))) - 1;
}
iter = set_iter_init(set, NULL);
while(NULL != (tuple = set_iter_next(iter, set)))
{
new_tuple = tuple_new(dim);
for(i = 0; i < dim; i++)
tuple_set_elem(new_tuple, i, elem_copy(tuple_get_elem(tuple, idx[i])));
if (list == NULL)
list = list_new_tuple(new_tuple);
else
list_add_tuple(list, new_tuple);
tuple_free(tuple);
tuple_free(new_tuple);
}
set_iter_exit(iter, set);
free(idx);
if (list == NULL)
{
assert(set_get_members(set) == 0);
new_set = set_empty_new(dim);
}
else
{
new_set = set_new_from_list(list, SET_CHECK_QUIET);
assert(set_get_members(new_set) <= set_get_members(set));
list_free(list);
}
return new_set;
}
/* Is A subset (or equal) of B */
bool set_is_subseteq(const Set* set_a, const Set* set_b)
{
SetIter* iter;
Tuple* tuple;
bool is_subset = true;
assert(set_is_valid(set_a));
assert(set_is_valid(set_b));
/* If A is the empty set and B is non empty,
* A is a subset of B
*/
if (set_a->head.members == 0)
return true;
if (set_a->head.dim != set_b->head.dim)
{
if (stmt_trigger_warning(165))
{
fprintf(stderr, "--- Warning 165: Comparison of different dimension sets.\n");
set_print(stderr, set_a);
fputc('\n', stderr);
set_print(stderr, set_b);
fputc('\n', stderr);
}
return false;
}
if (set_a->head.members > set_b->head.members)
return false;
iter = set_iter_init(set_a, NULL);
while(is_subset && NULL != (tuple = set_iter_next(iter, set_a)))
{
is_subset = set_lookup(set_b, tuple);
tuple_free(tuple);
}
set_iter_exit(iter, set_a);
return is_subset;
}
/* A is real subset of B */
bool set_is_subset(const Set* set_a, const Set* set_b)
{
assert(set_is_valid(set_a));
assert(set_is_valid(set_b));
if (set_a->head.members >= set_b->head.members)
return false;
return set_is_subseteq(set_a, set_b);
}
/* A has the same elements as B */
bool set_is_equal(const Set* set_a, const Set* set_b)
{
assert(set_is_valid(set_a));
assert(set_is_valid(set_b));
if (set_a->head.members != set_b->head.members)
return false;
return set_is_subseteq(set_a, set_b);
}
/* n elements in set
* k elements in subset
* i index for counter
*/
/*lint -sem(counter_inc, 1p == 3n && 2n > 0 && 3n > 0 && 4n >= 0, @n > 0) */
static int counter_inc(int* counter, int n, int k, int i)
{
int ret = 0;
counter[i]++;
if (counter[i] == n - i)
{
if (i == k - 1)
return 1;
ret = counter_inc(counter, n, k, i + 1);
counter[i] = counter[i + 1] + 1;
}
return ret;
}
List* set_subsets_list(
const Set* set,
int subset_size,
List* list,
SetIterIdx* idx)
{
int* counter;
int i;
Set* subset;
Tuple* tuple;
Entry* entry;
Numb* numb;
assert(set_is_valid(set));
assert(subset_size >= 0);
assert(subset_size <= set->head.members);
assert(idx != NULL);
if (subset_size == 0)
{
subset = set_empty_new(set_get_dim(set));
numb = numb_new_integer(*idx);
*idx += 1;
tuple = tuple_new(1);
tuple_set_elem(tuple, 0, elem_new_numb(numb));
entry = entry_new_set(tuple, subset);
list = list_new_entry(entry);
numb_free(numb);
entry_free(entry);
tuple_free(tuple);
set_free(subset);
return list;
}
counter = malloc(sizeof(*counter) * (size_t)subset_size);
assert(counter != NULL);
for(i = 0; i < subset_size; i++)
counter[i] = subset_size - 1 - i;
do
{
List* subset_list = NULL;
for(i = 0; i < subset_size; i++)
{
tuple = set_get_tuple(set, counter[i]);
if (subset_list == NULL)
subset_list = list_new_tuple(tuple);
else
list_add_tuple(subset_list, tuple);
tuple_free(tuple);
}
assert(subset_list != NULL);
subset = set_new_from_list(subset_list, SET_CHECK_NONE); /* NO_HASH ? */
list_free(subset_list);
numb = numb_new_integer(*idx);
*idx += 1;
tuple = tuple_new(1);
tuple_set_elem(tuple, 0, elem_new_numb(numb));
entry = entry_new_set(tuple, subset);
if (list == NULL)
list = list_new_entry(entry);
else
list_add_entry(list, entry);
numb_free(numb);
entry_free(entry);
tuple_free(tuple);
set_free(subset);
}
while(!counter_inc(counter, set->head.members, subset_size, 0));
free(counter);
assert(list != NULL);
return list;
}
zimpl-3.3.6/src/zimpl/zimpl.c 0000644 0014172 0006025 00000034541 13304236715 016011 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: zimpl.c */
/* Name....: Zuse Institute Mathematical Programming Language */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include
#include "zimpl/mshell.h"
#include "zimpl/stkchk.h"
#include "zimpl/random.h"
#include "zimpl/blkmem.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/define.h"
#include "zimpl/bound.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/stmt.h"
#include "zimpl/local.h"
#include "zimpl/list.h"
#include "zimpl/entry.h"
#include "zimpl/conname.h"
#include "zimpl/xlpglue.h"
#include "zimpl/zlpglue.h"
#include "zimpl/prog.h"
#include "zimpl/metaio.h"
#include "zimpl/strstore.h"
#include "zimpl/zimpllib.h"
extern int yydebug;
extern int yy_flex_debug;
static const char* const options = "bD:fF:hl:mn:o:OP:rs:t:v:V";
static const char* const usage = "usage: %s [options] file ...\n";
static const char* const title = "This file was automatically generated by Zimpl";
static const char* const help =
"\n" \
" -b enable bison debugging output.\n" \
" -D name=value assign value to parameter name.\n" \
" -f enable flex debugging output.\n" \
" -F filter filter output, for example \"gzip -c >%%s.gz\"\n" \
" -h show this help.\n" \
" -l length Maximum length of names in output file.\n" \
" -m write CPLEX MIP start value file.\n"
" -n cm|cn|cf name constraint make/name/full\n" \
" -o outfile select name for the output file. Default is the name of\n" \
" the input file without extension.\n" \
" -P cmd Pipe input through command, e.g. \"cpp -DONLY_X %%s\"\n" \
" -r write CPLEX branching order file.\n" \
" -s seed random number generator seed.\n" \
" -t lp|mps|hum|rlp|pip select output format. Either LP (default), MPS format,\n" \
" human readable HUM, randomly permuted LP, or PIP polynomial IP.\n" \
" -v[0-5] verbosity level: 0 = quiet, 1 = default, up to 5 = debug\n" \
" -V print program version\n" \
" filename is the name of the input ZPL file.\n" \
"\n" ;
/* " -O optimize LP by preprocessing.\n" \
*/
#ifdef WITH_CALLTRACE /* Does only work with gcc */
void __cyg_profile_func_enter(void *this_fn, void *call_site) __attribute__((no_instrument_function));
void __cyg_profile_func_exit(void *this_fn, void *call_site) __attribute__((no_instrument_function));
static int call_depth = 0;
void __cyg_profile_func_enter(void *this_fn, void *call_site)
{
call_depth++;
fprintf(stderr, "%p %d\n", this_fn, call_depth);
}
void __cyg_profile_func_exit(void *this_fn, void *call_site)
{
call_depth--;
}
#endif
//lint -sem(add_extention, 1p, 2p, @p)
static char* add_extention(const char* filename, const char* extension)
{
char* basename;
assert(filename != NULL);
assert(strlen(filename) > 0);
assert(extension != NULL);
basename = malloc(strlen(filename) + strlen(extension) + 1);
assert(basename != NULL);
strcpy(basename, filename);
return strcat(basename, extension); /*lint !e429 suppress 'Custodial pointer 'basename' has not been freed or returned' */
}
static const char* strip_path(const char* filename)
{
const char* s;
assert(filename != NULL);
assert(strlen(filename) > 0);
s = strrchr(filename, DIRSEP);
return (s == NULL) ? filename : s + 1;
}
static char* strip_extension(char* filename)
{
int i;
assert(filename != NULL);
assert(strlen(filename) > 0);
for(i = (int)strlen(filename) - 1; i >= 0; i--)
if (filename[i] == DIRSEP || filename[i] == '.')
break;
if (i >= 0 && filename[i] == '.')
filename[i] = '\0';
i = (int)strlen(filename);
if (i == 0 || filename[i - 1] == DIRSEP)
{
fprintf(stderr, "*** Error 101: Bad filename\n");
exit(EXIT_FAILURE);
}
return filename;
}
static void check_write_ok(FILE* fp, const char* filename)
{
if (ferror(fp))
{
fprintf(stderr, "*** Error 102: File write error\n");
perror(filename);
}
}
int main(int argc, char* const* argv)
{
Prog* prog;
Set* set;
void* lp;
const char* extension = "";
char* filter = strdup("%s");
char* outfile;
char* tblfile;
char* ordfile;
char* mstfile;
char* basefile = NULL;
char* inppipe = NULL;
char* outpipe;
LpFormat format = LP_FORM_LPF;
FILE* fp;
bool write_order = false;
bool write_mst = false;
bool presolve = false;
int name_length = 0;
char* prog_text;
unsigned long seed = 13021967UL;
char** param_table;
int param_count = 0;
int c;
int i;
FILE* (*openfile)(const char*, const char*) = fopen;
int (*closefile)(FILE*) = fclose;
stkchk_init();
yydebug = 0;
yy_flex_debug = 0;
verbose = VERB_NORMAL;
param_table = malloc(sizeof(*param_table));
while((c = getopt(argc, argv, options)) != -1)
{
switch(c)
{
case 'b' :
yydebug = 1;
break;
case 'D' :
param_table =
realloc(param_table, ((unsigned int)param_count + 1) * sizeof(*param_table));
param_table[param_count] = strdup(optarg);
param_count++;
break;
case 'h' :
zpl_print_banner(stdout, true);
printf(usage, argv[0]);
puts(help);
exit(0);
case 'f' :
yy_flex_debug = 1;
break;
case 'F' :
free(filter);
filter = strdup(optarg);
openfile = popen;
closefile = pclose;
break;
case 'l' :
name_length = atoi(optarg);
break;
case 'm' :
write_mst = true;
break;
case 'n' :
if (*optarg != 'c')
{
fprintf(stderr, usage, argv[0]);
exit(0);
}
switch(optarg[1])
{
case 'm' :
conname_format(CON_FORM_MAKE);
break;
case 'n' :
conname_format(CON_FORM_NAME);
break;
case 'f' :
conname_format(CON_FORM_FULL);
break;
default :
fprintf(stderr, usage, argv[0]);
exit(0);
}
break;
case 'o' :
basefile = strdup(optarg);
break;
case 'O' :
presolve = true;
break;
case 'P' :
inppipe = strdup(optarg);
break;
case 's' :
seed = (unsigned long)atol(optarg);
break;
case 'r' :
write_order = true;
break;
case 't' :
switch(tolower(*optarg))
{
case 'h' :
format = LP_FORM_HUM;
break;
case 'm' :
format = LP_FORM_MPS;
break;
case 'l' :
format = LP_FORM_LPF;
break;
case 'p' :
format = LP_FORM_PIP;
break;
case 'r' :
format = LP_FORM_RLP;
break;
default :
if (verbose > VERB_QUIET)
fprintf(stderr,
"--- Warning 103: Output format \"%s\" not supported, using LP format\n",
optarg);
format = LP_FORM_LPF;
break;
}
break;
case 'v' :
verbose = atoi(optarg);
break;
case 'V' :
printf("%s\n", VERSION);
exit(0);
case '?':
fprintf(stderr, usage, argv[0]);
exit(0);
default :
abort();
}
}
if ((argc - optind) < 1)
{
fprintf(stderr, usage, argv[0]);
exit(0);
}
zpl_print_banner(stdout, true);
if (basefile == NULL)
basefile = strip_extension(strdup(strip_path(argv[optind])));
switch(format)
{
case LP_FORM_LPF :
extension = ".lp";
break;
case LP_FORM_MPS :
extension = ".mps";
break;
case LP_FORM_HUM :
extension = ".hum";
break;
case LP_FORM_RLP :
extension = ".rlp";
break;
case LP_FORM_PIP :
extension = ".pip";
break;
default :
abort();
}
assert(extension != NULL);
outfile = add_extention(basefile, extension);
tblfile = add_extention(basefile, ".tbl");
ordfile = add_extention(basefile, ".ord");
mstfile = add_extention(basefile, ".mst");
outpipe = malloc(strlen(basefile) + strlen(filter) + 256);
assert(outpipe != NULL);
blk_init();
str_init();
rand_init(seed);
numb_init(true);
elem_init();
set_init();
mio_init();
interns_init();
local_init();
/* Make symbol to hold entries of internal variables
*/
set = set_pseudo_new();
(void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, ENTRY_NULL);
set_free(set);
/* Now store the param defines
*/
for(i = 0; i < param_count; i++)
zpl_add_parameter(param_table[i]);
/* Next we read in the zpl program(s)
*/
prog = prog_new();
for(i = optind; i < argc; i++)
prog_load(prog, inppipe, argv[i]);
if (prog_is_empty(prog))
{
fprintf(stderr, "*** Error 168: No program statements to execute\n");
exit(EXIT_FAILURE);
}
if (verbose >= VERB_DEBUG)
prog_print(stderr, prog);
lp = xlp_alloc(argv[optind], write_mst || write_order, NULL);
zlp_setnamelen(lp, name_length);
prog_execute(prog, lp);
/* Presolve
*/
if (presolve)
fprintf(stderr, "--- Warning: Presolve no longer support. If you need it, send me an email\n");
#if 0
if (!zlp_presolve())
exit(EXIT_SUCCESS);
#endif
if (verbose >= VERB_NORMAL)
zlp_stat(lp);
/* Write order file
*/
if (write_order)
{
sprintf(outpipe, filter, ordfile, "ord");
if (verbose >= VERB_NORMAL)
printf("Writing [%s]\n", outpipe);
if (NULL == (fp = (*openfile)(outpipe, "w")))
{
fprintf(stderr, "*** Error 104: File open failed ");
perror(ordfile);
exit(EXIT_FAILURE);
}
zlp_orderfile(lp, fp, format);
check_write_ok(fp, ordfile);
(void)(*closefile)(fp);
}
/* Write MST file
*/
if (write_mst)
{
sprintf(outpipe, filter, mstfile, "mst");
if (verbose >= VERB_NORMAL)
printf("Writing [%s]\n", outpipe);
if (NULL == (fp = (*openfile)(outpipe, "w")))
{
fprintf(stderr, "*** Error 104: File open failed ");
perror(mstfile);
exit(EXIT_FAILURE);
}
zlp_mstfile(lp, fp, format);
check_write_ok(fp, mstfile);
(void)(*closefile)(fp);
}
/* Write Output
*/
sprintf(outpipe, filter, outfile, "lp");
if (verbose >= VERB_NORMAL)
printf("Writing [%s]\n", outpipe);
if (NULL == (fp = (*openfile)(outpipe, "w")))
{
fprintf(stderr, "*** Error 104: File open failed ");
perror(outfile);
exit(EXIT_FAILURE);
}
if (format != LP_FORM_RLP)
prog_text = prog_tostr(prog, format == LP_FORM_MPS ? "* " : "\\ ", title, 128);
else
{
prog_text = malloc(strlen(title) + 4);
assert(prog_text != NULL);
sprintf(prog_text, "\\%s\n", title);
}
zlp_write(lp, fp, format, prog_text);
check_write_ok(fp, outfile);
(void)(*closefile)(fp);
/* We do not need the translation table for human readable format
* Has to be written after the LP file, so the scaling has been done.
*/
if (format != LP_FORM_HUM)
{
/* Write translation table
*/
sprintf(outpipe, filter, tblfile, "tbl");
if (verbose >= VERB_NORMAL)
printf("Writing [%s]\n", outpipe);
if (NULL == (fp = (*openfile)(outpipe, "w")))
{
fprintf(stderr, "*** Error 104: File open failed");
perror(tblfile);
exit(EXIT_FAILURE);
}
zlp_transtable(lp, fp, format);
check_write_ok(fp, tblfile);
(void)(*closefile)(fp);
}
free(prog_text);
if (verbose >= VERB_DEBUG)
symbol_print_all(stderr);
#if defined(__INSURE__) || !defined(NDEBUG) || defined(FREEMEM)
/* Now clean up.
*/
if (inppipe != NULL)
free(inppipe);
for(i = 0; i < param_count; i++)
free(param_table[i]);
free(param_table);
prog_free(prog);
local_exit();
interns_exit();
xlp_free(lp);
mio_exit();
symbol_exit();
define_exit();
set_exit();
elem_exit();
numb_exit();
str_exit();
blk_exit();
free(mstfile);
free(ordfile);
free(outfile);
free(tblfile);
free(basefile);
free(filter);
free(outpipe);
if (verbose >= VERB_NORMAL)
{
mem_display(stdout);
stkchk_maximum(stdout);
}
#endif /* __INSURE__ || !NDEBUG || FREEMEM */
return 0;
}
zimpl-3.3.6/src/zimpl/heap.h 0000644 0014172 0006025 00000005225 13304236715 015575 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: heap.h */
/* Name....: Heap Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2006-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _HEAP_H_
#define _HEAP_H_
#ifndef _ENTRY_H_
#error "Need to include entry.h before heap.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
union heap_data
{
Entry* entry;
};
typedef struct heap Heap;
typedef union heap_data HeapData;
typedef int (*HeapCmp)(HeapData, HeapData);
/*lint -sem( heap_new_entry, 1n > 0 && 2p == 1, @P > malloc(1P)) */
extern Heap* heap_new_entry(int size, HeapCmp entry_cmp);
/*lint -sem( heap_free, 1p == 1) */
extern void heap_free(Heap* heap);
/*lint -sem( heap_is_valid, 1p == 1) */
extern bool heap_is_valid(const Heap* heap);
/*lint -sem( heap_push_entry, 1p == 1 && 2p == 1) */
extern void heap_push_entry(Heap* heap, Entry* entry);
/*lint -sem( heap_pop_entry, 1p == 1, @P > malloc(1P)) */
extern Entry* heap_pop_entry(Heap* heap);
/*lint -sem( heap_top_entry, 1p == 1, @P > malloc(1P)) */
extern const Entry* heap_top_entry(const Heap* heap);
/*lint -sem( heap_is_full, 1p == 1) */
extern bool heap_is_full(const Heap* heap);
/*lint -sem( heap_is_empty, 1p == 1) */
extern bool heap_is_empty(const Heap* heap);
#ifdef __cplusplus
}
#endif
#endif /* _HEAP_H_ */
zimpl-3.3.6/src/zimpl/xlpglue.h 0000644 0014172 0006025 00000006731 13304236715 016343 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: xlpglue.h */
/* Name....: Glue between numb/term and ratlp */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2003-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _XLPGLUE_H_
#define _XLPGLUE_H_
#ifndef _RATLPTYPES_H_
#error "Need to include ratlptypes.h before xlpglue.h"
#endif
#ifndef _MME_H_
#error "Need to include mme.h before xlpglue.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*lint -sem( xlp_alloc, nulterm(1) && 1p, @p) */
extern Lps* xlp_alloc(const char* name, bool need_startval, void* user_data);
/*lint -sem( xlp_free, 1p == 1) */
extern void xlp_free(Lps* lp);
/*lint -sem( xlp_conname, nulterm(1), 1p == 1 && 2p && nulterm(2)) */
extern bool xlp_conname_exists(const Lps* lp, const char* conname);
/*lint -sem( xlp_addcon_term, 1p == 1 && nulterm(2) && 2p && 4p == 1 && 5p == 1 && 7p == 1) */
extern bool xlp_addcon_term(Lps* lp, const char* name, ConType type,
const Numb* lhs, const Numb* rhs, unsigned int flags, const Term* term);
/*lint -sem( xlp_addvar, 1p == 1 && nulterm(2) && 2p && 4p == 1 && 5p == 1 && 6p == 1 && 7p == 1, @p) */
extern Var* xlp_addvar(Lps* lp, const char* name, VarClass usevarclass,
const Bound* lower, const Bound* upper, const Numb* priority, const Numb* startval);
/*lint -sem( xlp_addsos, 1p == 1 && nulterm(2) && 2p && 4p == 1 && 5p == 1, @p) */
extern int xlp_addsos_term(Lps* lp, const char* name, SosType type,
const Numb* priority, const Term* term);
/*lint -sem( xlp_getvarname, 1p == 1 && 2p == 1, @p) */
const char* xlp_getvarname(const Lps* lp, const Var* var);
/*lint -sem( xlp_getclass, 1p == 1 && 2p == 1) */
extern VarClass xlp_getclass(const Lps* lp, const Var* var);
/*lint -sem( xlp_getlower, 1p == 1 && 2p == 1, @p) */
extern Bound* xlp_getlower(const Lps* lp, const Var* var);
/*lint -sem( xlp_getupper, 1p == 1, @p) */
extern Bound* xlp_getupper(const Lps* lp, const Var* var);
/*lint -sem( xlp_objname, 1p == 1 && nulterm(2) && 2p) */
extern bool xlp_setobj(Lps* lp, const char* name, bool minimize);
/*lint -sem( xlp_addtocost, 1p == 1 && 2p == 1 && 3p == 1) */
extern void xlp_addtocost(Lps* lp, Var* var, const Numb* cost);
#ifdef __cplusplus
}
#endif
#endif /* _XLPGLUE_H */
zimpl-3.3.6/src/zimpl/mmlscan.l 0000644 0014172 0006025 00000034126 13304236715 016320 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: mmlscan.l */
/* Name....: MML Lexcal Analyser */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
%{
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#pragma clang diagnostic ignored "-Wunused-macros"
#pragma clang diagnostic ignored "-Wmissing-noreturn"
#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
#pragma GCC diagnostic ignored "-Wsign-compare"
/*lint -e527 -e835 -e717 */
#include
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/define.h"
#include "zimpl/stmt.h"
#include "zimpl/strstore.h"
#include "zimpl/mmlparse2.h"
extern void yyerror(const char* s);
#define YY_DECL int yylex(YYSTYPE* lval)
YY_DECL;
static int yycolumn = 0;
static int yydecl = 0;
%}
%option noyylineno
%option never-interactive
%option noyywrap
%option noyymore
%option noreject
%option nounput
%pointer
%%
"**"|"^" { yycolumn += yyleng; return POW; }
":=" { yycolumn += yyleng; return ASGN; }
"==" { yycolumn += yyleng; return CMP_EQ; }
"<=" { yycolumn += yyleng; return CMP_LE; }
">=" { yycolumn += yyleng; return CMP_GE; }
"<" { yycolumn += yyleng; return CMP_LT; }
">" { yycolumn += yyleng; return CMP_GT; }
"!=" { yycolumn += yyleng; return CMP_NE; }
"!" { yycolumn += yyleng; return FAC; }
"not" { yycolumn += yyleng; return NOT; }
"and" { yycolumn += yyleng; return AND; }
"or" { yycolumn += yyleng; return OR; }
"xor" { yycolumn += yyleng; return XOR; }
"set" { yycolumn += yyleng; yydecl = DECLSET; return DECLSET; }
"param" { yycolumn += yyleng; yydecl = DECLPAR; return DECLPAR; }
"var" { yycolumn += yyleng; yydecl = DECLVAR; return DECLVAR; }
"maximize" { yycolumn += yyleng; yydecl = DECLMAX; return DECLMAX; }
"minimize" { yycolumn += yyleng; yydecl = DECLMIN; return DECLMIN; }
"subto" { yycolumn += yyleng; yydecl = DECLSUB; return DECLSUB; }
"sos" { yycolumn += yyleng; yydecl = DECLSOS; return DECLSOS; }
"defnumb" { yycolumn += yyleng; yydecl = DEFNUMB; return DEFNUMB; }
"defstrg" { yycolumn += yyleng; yydecl = DEFSTRG; return DEFSTRG; }
"defbool" { yycolumn += yyleng; yydecl = DEFBOOL; return DEFBOOL; }
"defset" { yycolumn += yyleng; yydecl = DEFSET; return DEFSET; }
"in" { yycolumn += yyleng; return IN; }
"with"|"|" { yycolumn += yyleng; return WITH; }
"do"|":" { yycolumn += yyleng; return DO; }
"binary" { yycolumn += yyleng; return BINARY; }
"integer" { yycolumn += yyleng; return INTEGER; }
"real" { yycolumn += yyleng; return REAL; }
"sum" { yycolumn += yyleng; return SUM; }
"prod" { yycolumn += yyleng; return PROD; }
"forall" { yycolumn += yyleng; return FORALL; }
"exists" { yycolumn += yyleng; return EXISTS; }
"vif" { yycolumn += yyleng; return VIF; }
"if" { yycolumn += yyleng; return IF; }
"then" { yycolumn += yyleng; return THEN; }
"else" { yycolumn += yyleng; return ELSE; }
"end" { yycolumn += yyleng; return END; }
"to" { yycolumn += yyleng; return TO; }
".." { yycolumn += yyleng; return UNTIL; }
"by" { yycolumn += yyleng; return BY; }
"union" { yycolumn += yyleng; return UNION; }
"inter" { yycolumn += yyleng; return INTER; }
"symdiff" { yycolumn += yyleng; return SYMDIFF; }
"cross" { yycolumn += yyleng; return CROSS; }
"proj" { yycolumn += yyleng; return PROJ; }
"without"|"\\" { yycolumn += yyleng; return WITHOUT; }
"mod"|"modulo" { yycolumn += yyleng; return MOD; }
"div" { yycolumn += yyleng; return DIV; }
"min" { yycolumn += yyleng; return MIN; }
"max" { yycolumn += yyleng; return MAX; }
"argmin" { yycolumn += yyleng; return ARGMIN; }
"argmax" { yycolumn += yyleng; return ARGMAX; }
"read" { yycolumn += yyleng; return READ; }
"as" { yycolumn += yyleng; return AS; }
"skip" { yycolumn += yyleng; return SKIP; }
"use" { yycolumn += yyleng; return USE; }
"comment" { yycolumn += yyleng; return COMMENT; }
"scale" { yycolumn += yyleng; return SCALE; }
"separate" { yycolumn += yyleng; return SEPARATE; }
"checkonly" { yycolumn += yyleng; return CHECKONLY; }
"indicator" { yycolumn += yyleng; return INDICATOR; }
"card" { yycolumn += yyleng; return CARD; }
"abs" { yycolumn += yyleng; return ABS; }
"vabs" { yycolumn += yyleng; return VABS; }
"sgn" { yycolumn += yyleng; return SGN; }
"round" { yycolumn += yyleng; return ROUND; }
"floor" { yycolumn += yyleng; return FLOOR; }
"ceil" { yycolumn += yyleng; return CEIL; }
"log" { yycolumn += yyleng; return LOG; }
"ln" { yycolumn += yyleng; return LN; }
"exp" { yycolumn += yyleng; return EXP; }
"sqrt" { yycolumn += yyleng; return SQRT; }
"sin" { yycolumn += yyleng; return SIN; }
"cos" { yycolumn += yyleng; return COS; }
"tan" { yycolumn += yyleng; return TAN; }
"asin" { yycolumn += yyleng; return ASIN; }
"acos" { yycolumn += yyleng; return ACOS; }
"atan" { yycolumn += yyleng; return ATAN; }
"pow" { yycolumn += yyleng; return POWER; }
"sgnpow" { yycolumn += yyleng; return SGNPOW; }
"priority" { yycolumn += yyleng; return PRIORITY; }
"startval" { yycolumn += yyleng; return STARTVAL; }
"default" { yycolumn += yyleng; return DEFAULT; }
"subsets" { yycolumn += yyleng; return SUBSETS; }
"powerset" { yycolumn += yyleng; return POWERSET; }
"indexset" { yycolumn += yyleng; return INDEXSET; }
"print" { yycolumn += yyleng; return PRINT; }
"check" { yycolumn += yyleng; return CHECK; }
"infinity" { yycolumn += yyleng; return INFTY; }
"random" { yycolumn += yyleng; return RANDOM; }
"ord" { yycolumn += yyleng; return ORD; }
"type1" { yycolumn += yyleng; return TYPE1; }
"type2" { yycolumn += yyleng; return TYPE2; }
"implicit" { yycolumn += yyleng; return IMPLICIT; }
"length" { yycolumn += yyleng; return LENGTH; }
"substr" { yycolumn += yyleng; return SUBSTR; }
"match" { yycolumn += yyleng; return MATCH; }
[0-9]+("."[0-9]+)?([eEdD][-+]?[0-9]+)? {
yycolumn += yyleng;
lval->numb = numb_new_ascii(yytext);
/* sscanf(yytext, "%lf", &lval->numb);*/
return NUMB;
}
"."[0-9]+([eEdD][-+]-?[0-9]+)? {
yycolumn += yyleng;
lval->numb = numb_new_ascii(yytext);
/* sscanf(yytext, "%lf", &lval->numb);*/
return NUMB;
}
[A-Za-z_][A-Za-z0-9_]* {
Symbol* sym;
Define* def;
char errmsg[256];
int what;
yycolumn += yyleng;
/* If it is sure that this is the name for a constraint or
* objective, or sos, we do not need to lookup the name.
*/
if (yydecl == DECLSUB || yydecl == DECLMIN || yydecl == DECLMAX
|| yydecl == DECLSOS)
yydecl = 0;
/* If it is sure that this is the name for a set, param or var
* we check only if the name is unused and otherwise give
* an appropriate error message.
*/
else if (yydecl == DECLSET || yydecl == DECLPAR || yydecl == DECLVAR
|| yydecl == DEFNUMB || yydecl == DEFSTRG || yydecl == DEFBOOL
|| yydecl == DEFSET)
{
if (NULL != symbol_lookup(yytext) || NULL != define_lookup(yytext))
{
/* Allow to declare parameter on the command line and ignore the
* redeclarations in the zimpl code later on
*/
if (yydecl == DECLPAR)
{
extern void yywarning(int no, const char* s);
sprintf(errmsg, "Redefinition of parameter %s ignored\n", yytext);
yywarning(252, errmsg);
yydecl = 0;
return EOF;
}
sprintf(errmsg, "Name \"%s\" already in use\n", yytext);
yyerror(errmsg);
}
what = yydecl;
yydecl = 0;
/* if this is a define, we have to install it here,
* so that recursive call succseed.
*/
switch(what)
{
case DEFNUMB :
lval->def = define_new(str_new(yytext), DEF_NUMB);
return DEFNAME;
case DEFSTRG :
lval->def = define_new(str_new(yytext), DEF_STRG);
return DEFNAME;
case DEFBOOL :
lval->def = define_new(str_new(yytext), DEF_BOOL);
return DEFNAME;
case DEFSET :
lval->def = define_new(str_new(yytext), DEF_SET);
return DEFNAME;
default :
break;
}
}
else
{
assert(yydecl == 0);
if (NULL != (sym = symbol_lookup(yytext)))
{
lval->sym = sym;
switch(symbol_get_type(sym))
{
case SYM_NUMB :
return NUMBSYM;
case SYM_STRG :
return STRGSYM;
case SYM_VAR :
return VARSYM;
case SYM_SET :
return SETSYM;
case SYM_ERR : /* should not happen */
sprintf(errmsg, "Symbol \"%s\" not initialised\n", yytext);
yyerror(errmsg);
default :
abort();
}
}
if (NULL != (def = define_lookup(yytext)))
{
lval->def = def;
switch(define_get_type(def))
{
case DEF_NUMB :
return NUMBDEF;
case DEF_STRG :
return STRGDEF;
case DEF_BOOL :
return BOOLDEF;
case DEF_SET :
return SETDEF;
case DEF_ERR : /* should not happen */
sprintf(errmsg, "Define \"%s\" not initialised\n", yytext);
yyerror(errmsg);
default :
abort();
}
}
}
lval->name = str_new(yytext);
return NAME;
}
\"[^\"]*\" {
yycolumn += yyleng;
yytext[strlen(yytext) - 1] = '\0';
lval->strg = str_new(yytext + 1);
return STRG;
}
\'[^\']*\' {
yycolumn += yyleng;
yytext[strlen(yytext) - 1] = '\0';
lval->strg = str_new(yytext + 1);
return STRG;
}
[[:space:]]+ { yycolumn += yyleng; }
. { yycolumn += yyleng; return *yytext; }
<> { yycolumn += yyleng; return EOF; }
%%
static const Stmt* yystmt = NULL;
void yyerror(const char* s)
{
fprintf(stderr, "*** Error 800: File %s Line %d : %s\n",
stmt_get_filename(yystmt), stmt_get_lineno(yystmt), s);
show_source(stderr, stmt_get_text(yystmt), yycolumn);
zpl_exit(EXIT_FAILURE);
}
void yywarning(int no, const char* s)
{
if (stmt_trigger_warning(no))
fprintf(stderr,
"*** Warning %d: File %s Line %d : %s\n",
no, stmt_get_filename(yystmt), stmt_get_lineno(yystmt), s);
}
const Stmt* scan_get_stmt(void)
{
return yystmt;
}
int scan_get_column(void)
{
return yycolumn;
}
void parse_stmt(const Stmt* stmt)
{
YY_BUFFER_STATE state;
yy_delete_buffer(YY_CURRENT_BUFFER);
yystmt = stmt;
yycolumn = 0;
state = yy_scan_string(stmt_get_text(stmt));
if (yyparse() != 0)
{
fprintf(stderr, "*** Error 801: Parser failed\n");
zpl_exit(EXIT_FAILURE);
}
yy_delete_buffer(state);
}
zimpl-3.3.6/src/zimpl/hash.c 0000644 0014172 0006025 00000022626 13304236715 015602 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: hash.c */
/* Name....: Hash Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/blkmem.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/entry.h"
#include "zimpl/mono.h"
#include "zimpl/hash.h"
#define HASH_SID 0x48617368
typedef struct hash_element HElem;
typedef struct set_elem_idx SetElemIdx;
struct set_elem_idx
{
const Elem* elem;
int idx;
};
struct hash_element
{
union
{
const Tuple* tuple;
const Entry* entry;
SetElemIdx elem_idx;
const Numb* numb;
const Mono* mono;
} value;
HElem* next;
};
struct hash
{
SID
unsigned int size;
int elems;
HashType type;
HElem** bucket;
};
static void hash_statist(FILE* fp, const Hash* hash);
static bool hash_is_valid(const Hash* hash)
{
return ((hash != NULL)
&& (hash->type == HASH_TUPLE || hash->type == HASH_ENTRY
|| hash->type == HASH_ELEM_IDX || hash->type == HASH_NUMB
|| hash->type == HASH_MONO)
&& SID_ok(hash, HASH_SID));
}
Hash* hash_new(HashType type, int size)
{
static const unsigned int bucket_size[] =
{
53U, 103U, 503U, 1009U, 5003U, 10007U, 50021U, 100003U, 500009U, 1000003U,
5000011U, 10000019U, 50000017U, 0U
};
Hash* hash = calloc(1, sizeof(*hash));
int i;
assert(hash != NULL);
assert(size >= 0);
/* This is a linear search, but if the number of elements is large,
* it will hardly matter ;-)
*/
for(i = 0; bucket_size[i] < (unsigned int)size && bucket_size[i + 1] != 0; i++)
;
hash->size = bucket_size[i];
assert(hash->size > 11);
hash->elems = 0;
hash->type = type;
hash->bucket = calloc(hash->size, sizeof(*hash->bucket));
assert(hash->bucket != NULL);
SID_set(hash, HASH_SID);
assert(hash_is_valid(hash));
return hash;
}
void hash_free(Hash* hash)
{
HElem* he;
HElem* hq;
unsigned int i;
assert(hash_is_valid(hash));
if (verbose >= VERB_CHATTER)
hash_statist(stderr, hash);
SID_del(hash);
for(i = 0; i < hash->size; i++)
{
for(he = hash->bucket[i]; he != NULL; he = hq)
{
hq = he->next;
blk_free(he, sizeof(*he));
}
}
free(hash->bucket);
free(hash);
}
void hash_add_tuple(Hash* hash, const Tuple* tuple)
{
HElem* he = blk_alloc(sizeof(*he));
unsigned int hcode;
assert(hash_is_valid(hash));
assert(tuple_is_valid(tuple));
assert(hash->type == HASH_TUPLE);
assert(he != NULL);
hcode = tuple_hash(tuple) % hash->size;
he->value.tuple = tuple;
he->next = hash->bucket[hcode];
hash->bucket[hcode] = he;
hash->elems++;
}
void hash_add_entry(Hash* hash, const Entry* entry)
{
HElem* he = blk_alloc(sizeof(*he));
const Tuple* tuple;
unsigned int hcode;
assert(hash_is_valid(hash));
assert(entry_is_valid(entry));
assert(hash->type == HASH_ENTRY);
assert(he != NULL);
tuple = entry_get_tuple(entry);
hcode = tuple_hash(tuple) % hash->size;
he->value.entry = entry;
he->next = hash->bucket[hcode];
hash->bucket[hcode] = he;
hash->elems++;
}
void hash_add_numb(Hash* hash, const Numb* numb)
{
HElem* he = blk_alloc(sizeof(*he));
unsigned int hcode;
assert(hash_is_valid(hash));
assert(numb_is_valid(numb));
assert(hash->type == HASH_NUMB);
assert(he != NULL);
hcode = numb_hash(numb) % hash->size;
he->value.numb = numb;
he->next = hash->bucket[hcode];
hash->bucket[hcode] = he;
hash->elems++;
}
void hash_add_mono(Hash* hash, const Mono* mono)
{
HElem* he = blk_alloc(sizeof(*he));
unsigned int hcode;
assert(hash_is_valid(hash));
assert(mono_is_valid(mono));
assert(hash->type == HASH_MONO);
assert(he != NULL);
hcode = mono_hash(mono) % hash->size;
he->value.mono = mono;
he->next = hash->bucket[hcode];
hash->bucket[hcode] = he;
hash->elems++;
}
bool hash_has_tuple(const Hash* hash, const Tuple* tuple)
{
unsigned int hcode = tuple_hash(tuple) % hash->size;
HElem* he;
assert(hash_is_valid(hash));
assert(tuple_is_valid(tuple));
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (!tuple_cmp(he->value.tuple, tuple))
break;
return he != NULL;
}
bool hash_has_entry(const Hash* hash, const Tuple* tuple)
{
unsigned int hcode = tuple_hash(tuple) % hash->size;
HElem* he;
assert(hash_is_valid(hash));
assert(tuple_is_valid(tuple));
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (!entry_cmp(he->value.entry, tuple))
break;
return he != NULL;
}
bool hash_has_numb(const Hash* hash, const Numb* numb)
{
unsigned int hcode = numb_hash(numb) % hash->size;
HElem* he;
assert(hash_is_valid(hash));
assert(numb_is_valid(numb));
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (numb_equal(he->value.numb, numb))
break;
return he != NULL;
}
/* Liefert NULL wenn nicht gefunden.
*/
const Entry* hash_lookup_entry(const Hash* hash, const Tuple* tuple)
{
unsigned int hcode = tuple_hash(tuple) % hash->size;
HElem* he;
assert(hash_is_valid(hash));
assert(tuple_is_valid(tuple));
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (!entry_cmp(he->value.entry, tuple))
break;
if (he == NULL)
return NULL;
assert(he != NULL);
assert(entry_is_valid(he->value.entry));
return he->value.entry;
}
/* Liefert NULL wenn nicht gefunden.
*/
const Mono* hash_lookup_mono(const Hash* hash, const Mono* mono)
{
unsigned int hcode = mono_hash(mono) % hash->size;
HElem* he;
assert(hash_is_valid(hash));
assert(mono_is_valid(mono));
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (mono_equal(he->value.mono, mono))
break;
if (he == NULL)
return NULL;
assert(he != NULL);
assert(mono_is_valid(he->value.mono));
return he->value.mono;
}
void hash_add_elem_idx(Hash* hash, const Elem* elem, int idx)
{
HElem* he = blk_alloc(sizeof(*he));
unsigned int hcode;
assert(hash_is_valid(hash));
assert(elem_is_valid(elem));
assert(he != NULL);
hcode = elem_hash(elem) % hash->size;
he->value.elem_idx.elem = elem;
he->value.elem_idx.idx = idx;
he->next = hash->bucket[hcode];
hash->bucket[hcode] = he;
hash->elems++;
}
/* Liefert -1 wenn nicht gefunden.
*/
int hash_lookup_elem_idx(const Hash* hash, const Elem* elem)
{
unsigned int hcode = elem_hash(elem) % hash->size;
HElem* he;
assert(hash_is_valid(hash));
assert(elem_is_valid(elem));
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (!elem_cmp(he->value.elem_idx.elem, elem))
break;
if (he == NULL)
return -1;
assert(he != NULL);
return he->value.elem_idx.idx;
}
static void hash_statist(FILE* fp, const Hash* hash)
{
HElem* he;
int min = (int)hash->size;
int max = 0;
int sum = 0;
int zeros = 0;
int filled = 0;
double avg = 0.0;
unsigned int i;
assert(fp != NULL);
assert(hash_is_valid(hash));
for(i = 0; i < hash->size; i++)
{
int count = 0;
for(he = hash->bucket[i]; he != NULL; he = he->next)
count++;
if (count == 0)
zeros++;
else
filled++;
if (count < min)
min = count;
if (count > max)
max = count;
sum += count;
}
assert(sum == hash->elems);
if (filled > 0)
avg = (double)sum / (double)filled;
fprintf(fp,
"HashStat: size=%8u sum=%6d min=%3d max=%3d avg=%4.1f zero=%6d filled=%6d\n",
hash->size, sum, min, max, avg, zeros, filled);
}
zimpl-3.3.6/src/zimpl/code.c 0000644 0014172 0006025 00000060175 13304236715 015572 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: code.c */
/* Name....: Code Node Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/stkchk.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/entry.h"
#include "zimpl/idxset.h"
#include "zimpl/rdefpar.h"
#include "zimpl/bound.h"
#include "zimpl/define.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/list.h"
#include "zimpl/stmt.h"
#include "zimpl/local.h"
#include "zimpl/code.h"
#include "zimpl/inst.h"
typedef union code_value CodeValue;
union code_value
{
Numb* numb;
const char* strg;
const char* name;
Tuple* tuple;
Set* set;
Term* term;
Entry* entry;
IdxSet* idxset;
bool bval;
int size;
List* list;
VarClass varclass;
ConType contype;
RDef* rdef;
RPar* rpar;
unsigned int bits;
Symbol* sym;
Define* def;
Bound* bound;
};
#define MAX_CHILDS 8
struct code_node
{
SID
CodeType type;
Inst eval;
CodeValue value;
CodeNode* child[MAX_CHILDS];
const Stmt* stmt;
int column;
};
#define CODE_SID 0x436f6465
static CodeNode* root = NULL;
static unsigned int inst_count = 0;
inline bool code_is_valid(const CodeNode* node)
{
return ((node != NULL) && SID_ok(node, CODE_SID));
}
CodeNode* code_new_inst(Inst inst, int childs, ...)
{
va_list ap;
CodeNode* node = calloc(1, sizeof(*node));
int i;
CodeNode* child;
assert(inst != INST_NULL);
assert(node != NULL);
assert(childs <= MAX_CHILDS);
node->type = CODE_ERR; /* call to eval() will set this */
node->eval = inst;
/* Das sollte eigendlich ein parameter sein, aber wozu bei jedem
* code_new diese Funktionen mit uebergeben.
*/
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
/*lint -save -e826 */
va_start(ap, childs);
for(i = 0; i < childs; i++)
{
child = va_arg(ap, CodeNode*);
assert((child == NULL) || code_is_valid(child));
node->child[i] = child;
}
va_end(ap);
/*lint -restore */
return node;
}
/* We eat the numb, i.e. we will free it!
*/
CodeNode* code_new_numb(Numb* numb)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(node != NULL);
node->type = CODE_NUMB;
node->eval = i_nop;
node->value.numb = numb;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
CodeNode* code_new_strg(const char* strg)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(strg != NULL);
assert(node != NULL);
node->type = CODE_STRG;
node->eval = i_nop;
node->value.strg = strg;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
CodeNode* code_new_name(const char* name)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(name != NULL);
assert(node != NULL);
node->type = CODE_NAME;
node->eval = i_nop;
node->value.name = name;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
CodeNode* code_new_size(int size)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(size >= 0);
assert(node != NULL);
node->type = CODE_SIZE;
node->eval = i_nop;
node->value.size = size;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
CodeNode* code_new_varclass(VarClass varclass)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(node != NULL);
node->type = CODE_VARCLASS;
node->eval = i_nop;
node->value.varclass = varclass;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
CodeNode* code_new_contype(ConType contype)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(node != NULL);
node->type = CODE_CONTYPE;
node->eval = i_nop;
node->value.contype = contype;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
CodeNode* code_new_bits(unsigned int bits)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(node != NULL);
node->type = CODE_BITS;
node->eval = i_nop;
node->value.bits = bits;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
CodeNode* code_new_symbol(Symbol* sym)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(node != NULL);
node->type = CODE_SYM;
node->eval = i_nop;
node->value.sym = sym;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
CodeNode* code_new_define(Define* def)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(node != NULL);
node->type = CODE_DEF;
node->eval = i_nop;
node->value.def = def;
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
/* We eat the bound, i.e. we will free it!
*/
CodeNode* code_new_bound(BoundType type)
{
CodeNode* node = calloc(1, sizeof(*node));
assert(node != NULL);
assert(type == BOUND_INFTY || type == BOUND_MINUS_INFTY);
node->type = CODE_BOUND;
node->eval = i_nop;
node->value.bound = bound_new(type, NULL);
node->stmt = scan_get_stmt();
node->column = scan_get_column();
SID_set(node, CODE_SID);
assert(code_is_valid(node));
return node;
}
void code_free_value(CodeNode* node)
{
assert(code_is_valid(node));
switch(node->type)
{
case CODE_ERR :
case CODE_VOID :
/* Kann passieren, wenn bei code_value_() ein bis dahin unbenutzter
* Knoten verwendet wird.
*/
break;
case CODE_NUMB :
assert(node->value.numb != NULL);
numb_free(node->value.numb);
break;
case CODE_STRG :
case CODE_NAME :
break;
case CODE_TUPLE :
assert(node->value.tuple != NULL);
tuple_free(node->value.tuple);
node->value.tuple = NULL;
node->type = CODE_ERR;
break;
case CODE_SET :
assert(node->value.set != NULL);
set_free(node->value.set);
node->value.set = NULL;
node->type = CODE_ERR;
break;
case CODE_TERM :
assert(node->value.term != NULL);
term_free(node->value.term);
node->value.term = NULL;
node->type = CODE_ERR;
break;
case CODE_ENTRY :
assert(node->value.entry != NULL);
entry_free(node->value.entry);
node->value.entry = NULL;
node->type = CODE_ERR;
break;
case CODE_IDXSET :
assert(node->value.idxset != NULL);
idxset_free(node->value.idxset);
node->value.entry = NULL;
node->type = CODE_ERR;
break;
case CODE_BOOL :
case CODE_SIZE :
break;
case CODE_LIST :
assert(node->value.list != NULL);
list_free(node->value.list);
node->value.list = NULL;
node->type = CODE_ERR;
break;
case CODE_VARCLASS :
case CODE_CONTYPE :
break;
case CODE_RDEF :
assert(node->value.rdef != NULL);
rdef_free(node->value.rdef);
node->value.rdef = NULL;
node->type = CODE_ERR;
break;
case CODE_RPAR :
assert(node->value.rpar != NULL);
rpar_free(node->value.rpar);
node->value.rpar = NULL;
node->type = CODE_ERR;
break;
case CODE_BITS :
break;
case CODE_SYM :
break;
case CODE_DEF :
break;
case CODE_BOUND :
assert(node->value.bound != NULL);
bound_free(node->value.bound);
break;
default :
abort();
}
}
void code_free(CodeNode* node)
{
int i;
for(i = 0; i < MAX_CHILDS; i++)
if (node->child[i] != NULL)
code_free(node->child[i]);
code_free_value(node);
free(node);
}
void code_set_child(CodeNode* node, int idx, CodeNode* child)
{
assert(code_is_valid(node));
assert(idx >= 0);
assert(idx < MAX_CHILDS);
assert(child != NULL);
node->child[idx] = child;
}
CodeType code_get_type(const CodeNode* node)
{
assert(code_is_valid(node));
return node->type;
}
Inst code_get_inst(const CodeNode* node)
{
assert(code_is_valid(node));
return node->eval;
}
void code_set_root(CodeNode* node)
{
assert(code_is_valid(node));
root = node;
}
CodeNode* code_get_root(void)
{
return root;
}
unsigned int code_get_inst_count()
{
return inst_count;
}
void code_clear_inst_count()
{
inst_count = 0;
}
static inline CodeNode* code_check_type(CodeNode* node, CodeType expected)
{
static const char* const tname[] =
{
"Error", "Number", "String", "Name", "Tuple", "Set", "Term", "Bool", "Size",
"IndexSet", "List", "Nothing", "Entry", "VarClass", "ConType",
"ReadDefinition", "ReadParameter", "BitFlag", "Symbol", "Define", "Bound"
};
assert(code_is_valid(node));
assert(sizeof(tname) / sizeof(tname[0]) > (size_t)node->type);
if (node->type != expected)
{
assert(sizeof(tname) / sizeof(tname[0]) > (size_t)expected);
fprintf(stderr, "*** Error 159: Type error, expected %s got %s\n",
tname[expected], tname[node->type]);
code_errmsg(node);
zpl_exit(EXIT_FAILURE);
}
return node;
}
void code_errmsg(const CodeNode* node)
{
fprintf(stderr, "*** File: %s Line %d\n",
stmt_get_filename(node->stmt),
stmt_get_lineno(node->stmt));
show_source(stderr, stmt_get_text(node->stmt), node->column);
if (verbose >= VERB_CHATTER)
local_print_all(stderr);
}
inline CodeNode* code_eval(CodeNode* node)
{
assert(code_is_valid(node));
inst_count++;
stkchk_used(); // record maximum stack use
return (*node->eval)(node);
}
bool code_prune_tree(CodeNode* node)
{
static Inst const prunable[] =
{
i_expr_abs, i_expr_sgn, i_expr_add, i_expr_card, i_expr_ceil, i_expr_div, i_expr_exp,
i_expr_sqrt, i_expr_fac, i_expr_floor, i_expr_if_else, i_expr_intdiv, i_expr_length, i_expr_ln,
i_expr_log, i_expr_ord, i_expr_prod, i_expr_round, i_expr_sum, i_expr_max,
i_expr_max2, i_expr_sglmax, i_expr_min, i_expr_min2, i_expr_sglmin, i_expr_mul,
i_expr_mod, i_expr_neg, i_expr_pow, i_expr_sub, i_expr_substr, NULL
};
bool is_all_const = true;
int i;
if (node->eval == (Inst)i_nop)
return true;
for(i = 0; i < MAX_CHILDS; i++)
{
if (node->child[i] != NULL)
{
bool is_const = code_prune_tree(node->child[i]);
/* Writing directly && code_prune_tree might not work
* due to shortcut evaluation.
*/
is_all_const = is_all_const && is_const;
}
}
if (is_all_const)
{
for(i = 0; prunable[i] != INST_NULL; i++)
if (prunable[i] == node->eval)
break;
if (prunable[i] == INST_NULL)
return false;
(void)code_eval(node);
for(i = 0; i < MAX_CHILDS; i++)
{
if (node->child[i] != NULL)
{
code_free(node->child[i]);
node->child[i] = NULL;
}
}
node->eval = i_nop;
}
return is_all_const;
}
/* ----------------------------------------------------------------------------
* Get Funktionen
* ----------------------------------------------------------------------------
*/
inline CodeNode* code_get_child(const CodeNode* node, int no)
{
assert(code_is_valid(node));
assert(no >= 0);
assert(no < MAX_CHILDS);
assert(node->child[no] != NULL);
return node->child[no];
}
inline const Numb* code_get_numb(CodeNode* node)
{
return code_check_type(node, CODE_NUMB)->value.numb;
}
inline const char* code_get_strg(CodeNode* node)
{
return code_check_type(node, CODE_STRG)->value.strg;
}
inline const char* code_get_name(CodeNode* node)
{
return code_check_type(node, CODE_NAME)->value.name;
}
inline const Tuple* code_get_tuple(CodeNode* node)
{
return code_check_type(node, CODE_TUPLE)->value.tuple;
}
inline const Set* code_get_set(CodeNode* node)
{
return code_check_type(node, CODE_SET)->value.set;
}
inline const IdxSet* code_get_idxset(CodeNode* node)
{
return code_check_type(node, CODE_IDXSET)->value.idxset;
}
inline const Entry* code_get_entry(CodeNode* node)
{
return code_check_type(node, CODE_ENTRY)->value.entry;
}
inline const Term* code_get_term(CodeNode* node)
{
return code_check_type(node, CODE_TERM)->value.term;
}
inline int code_get_size(CodeNode* node)
{
return code_check_type(node, CODE_SIZE)->value.size;
}
inline bool code_get_bool(CodeNode* node)
{
return code_check_type(node, CODE_BOOL)->value.bval;
}
inline const List* code_get_list(CodeNode* node)
{
return code_check_type(node, CODE_LIST)->value.list;
}
inline VarClass code_get_varclass(CodeNode* node)
{
return code_check_type(node, CODE_VARCLASS)->value.varclass;
}
inline ConType code_get_contype(CodeNode* node)
{
return code_check_type(node, CODE_CONTYPE)->value.contype;
}
inline const RDef* code_get_rdef(CodeNode* node)
{
return code_check_type(node, CODE_RDEF)->value.rdef;
}
inline const RPar* code_get_rpar(CodeNode* node)
{
return code_check_type(node, CODE_RPAR)->value.rpar;
}
inline unsigned int code_get_bits(CodeNode* node)
{
return code_check_type(node, CODE_BITS)->value.bits;
}
inline Symbol* code_get_symbol(CodeNode* node)
{
return code_check_type(node, CODE_SYM)->value.sym;
}
inline Define* code_get_define(CodeNode* node)
{
return code_check_type(node, CODE_DEF)->value.def;
}
inline const Bound* code_get_bound(CodeNode* node)
{
return code_check_type(node, CODE_BOUND)->value.bound;
}
/* ----------------------------------------------------------------------------
* Value Funktionen
* ----------------------------------------------------------------------------
*/
void code_value_numb(CodeNode* node, Numb* numb)
{
assert(code_is_valid(node));
code_free_value(node);
node->type = CODE_NUMB;
node->value.numb = numb;
}
void code_value_strg(CodeNode* node, const char* strg)
{
assert(code_is_valid(node));
assert(strg != NULL);
code_free_value(node);
node->type = CODE_STRG;
node->value.strg = strg;
}
void code_value_name(CodeNode* node, const char* name)
{
assert(code_is_valid(node));
assert(name != NULL);
code_free_value(node);
node->type = CODE_NAME;
node->value.name = name;
}
void code_value_tuple(CodeNode* node, Tuple* tuple)
{
assert(code_is_valid(node));
assert(tuple_is_valid(tuple));
code_free_value(node);
node->type = CODE_TUPLE;
node->value.tuple = tuple;
}
void code_value_set(CodeNode* node, Set* set)
{
assert(code_is_valid(node));
assert(set_is_valid(set));
code_free_value(node);
node->type = CODE_SET;
node->value.set = set;
}
void code_value_idxset(CodeNode* node, IdxSet* idxset)
{
assert(code_is_valid(node));
assert(idxset_is_valid(idxset));
code_free_value(node);
node->type = CODE_IDXSET;
node->value.idxset = idxset;
}
void code_value_entry(CodeNode* node, Entry* entry)
{
assert(code_is_valid(node));
assert(entry_is_valid(entry));
code_free_value(node);
node->type = CODE_ENTRY;
node->value.entry = entry;
}
void code_value_term(CodeNode* node, Term* term)
{
assert(code_is_valid(node));
assert(term_is_valid(term));
code_free_value(node);
node->type = CODE_TERM;
node->value.term = term;
}
Term* code_value_steal_term(CodeNode* node, int no)
{
CodeNode* child = code_get_child(node, no);
assert(code_is_valid(node));
assert(code_get_type(child) == CODE_TERM);
code_free_value(node);
node->type = CODE_TERM;
node->value.term = child->value.term;
child->type = CODE_ERR;
child->value.term = NULL;
return node->value.term;
}
void code_value_bool(CodeNode* node, bool bval)
{
assert(code_is_valid(node));
code_free_value(node);
node->type = CODE_BOOL;
node->value.bval = bval;
}
void code_value_size(CodeNode* node, int size)
{
assert(code_is_valid(node));
code_free_value(node);
node->type = CODE_SIZE;
node->value.size = size;
}
void code_value_list(CodeNode* node, List* list)
{
assert(code_is_valid(node));
assert(list_is_valid(list));
code_free_value(node);
node->type = CODE_LIST;
node->value.list = list;
}
void code_value_varclass(CodeNode* node, VarClass varclass)
{
assert(code_is_valid(node));
code_free_value(node);
node->type = CODE_VARCLASS;
node->value.varclass = varclass;
}
void code_value_contype(CodeNode* node, ConType contype)
{
assert(code_is_valid(node));
code_free_value(node);
node->type = CODE_CONTYPE;
node->value.contype = contype;
}
void code_value_rdef(CodeNode* node, RDef* rdef)
{
assert(code_is_valid(node));
assert(rdef_is_valid(rdef));
code_free_value(node);
node->type = CODE_RDEF;
node->value.rdef = rdef;
}
void code_value_rpar(CodeNode* node, RPar* rpar)
{
assert(code_is_valid(node));
assert(rpar_is_valid(rpar));
code_free_value(node);
node->type = CODE_RPAR;
node->value.rpar = rpar;
}
void code_value_bits(CodeNode* node, unsigned int bits)
{
assert(code_is_valid(node));
code_free_value(node);
node->type = CODE_BITS;
node->value.bits = bits;
}
void code_value_bound(CodeNode* node, Bound* bound)
{
assert(code_is_valid(node));
code_free_value(node);
node->type = CODE_BOUND;
node->value.bound = bound;
}
void code_value_void(CodeNode* node)
{
assert(code_is_valid(node));
code_free_value(node);
node->type = CODE_VOID;
}
void code_copy_value(CodeNode* dst, const CodeNode* src)
{
assert(code_is_valid(dst));
assert(code_is_valid(src));
code_free_value(dst);
switch(src->type)
{
case CODE_NUMB :
dst->value.numb = numb_copy(src->value.numb);
break;
case CODE_STRG :
dst->value.strg = src->value.strg;
break;
case CODE_NAME :
dst->value.name = src->value.name;
break;
case CODE_TUPLE:
dst->value.tuple = tuple_copy(src->value.tuple);
break;
case CODE_SET :
dst->value.set = set_copy(src->value.set);
break;
case CODE_IDXSET :
dst->value.idxset = idxset_copy(src->value.idxset);
break;
case CODE_ENTRY :
dst->value.entry = entry_copy(src->value.entry);
break;
case CODE_TERM :
dst->value.term = term_copy(src->value.term);
break;
case CODE_BOOL :
dst->value.bval = src->value.bval;
break;
case CODE_SIZE :
dst->value.size = src->value.size;
break;
case CODE_LIST :
dst->value.list = list_copy(src->value.list);
break;
case CODE_VARCLASS :
dst->value.varclass = src->value.varclass;
break;
case CODE_CONTYPE :
dst->value.contype = src->value.contype;
break;
case CODE_RDEF :
dst->value.rdef = rdef_copy(src->value.rdef);
break;
case CODE_RPAR :
dst->value.rpar = rpar_copy(src->value.rpar);
break;
case CODE_BITS :
dst->value.bits = src->value.bits;
break;
case CODE_BOUND :
dst->value.bound = bound_copy(src->value.bound);
break;
case CODE_VOID :
break;
default :
abort();
}
dst->type = src->type;
}
/* ----------------------------------------------------------------------------
* Macro Funktionen for better inlining
* ----------------------------------------------------------------------------
*/
CodeNode* code_eval_child(const CodeNode* node, int no)
{
return code_eval(code_get_child(node, no));
}
const Numb* code_eval_child_numb(const CodeNode* node, int no)
{
return code_get_numb(code_eval(code_get_child(node, no)));
}
const char* code_eval_child_strg(const CodeNode* node, int no)
{
return code_get_strg(code_eval(code_get_child(node, no)));
}
const char*code_eval_child_name(const CodeNode* node, int no)
{
return code_get_name(code_eval(code_get_child(node, no)));
}
const Tuple* code_eval_child_tuple(const CodeNode* node, int no)
{
return code_get_tuple(code_eval(code_get_child(node, no)));
}
const Set* code_eval_child_set(const CodeNode* node, int no)
{
return code_get_set(code_eval(code_get_child(node, no)));
}
const IdxSet* code_eval_child_idxset(const CodeNode* node, int no)
{
return code_get_idxset(code_eval(code_get_child(node, no)));
}
const Entry* code_eval_child_entry(const CodeNode* node, int no)
{
return code_get_entry(code_eval(code_get_child(node, no)));
}
const Term* code_eval_child_term(const CodeNode* node, int no)
{
return code_get_term(code_eval(code_get_child(node, no)));
}
int code_eval_child_size(const CodeNode* node, int no)
{
return code_get_size(code_eval(code_get_child(node, no)));
}
bool code_eval_child_bool(const CodeNode* node, int no)
{
return code_get_bool(code_eval(code_get_child(node, no)));
}
const List* code_eval_child_list(const CodeNode* node, int no)
{
return code_get_list(code_eval(code_get_child(node, no)));
}
VarClass code_eval_child_varclass(const CodeNode* node, int no)
{
return code_get_varclass(code_eval(code_get_child(node, no)));
}
ConType code_eval_child_contype(const CodeNode* node, int no)
{
return code_get_contype(code_eval(code_get_child(node, no)));
}
const RDef* code_eval_child_rdef(const CodeNode* node, int no)
{
return code_get_rdef(code_eval(code_get_child(node, no)));
}
const RPar* code_eval_child_rpar(const CodeNode* node, int no)
{
return code_get_rpar(code_eval(code_get_child(node, no)));
}
unsigned int code_eval_child_bits(const CodeNode* node, int no)
{
return code_get_bits(code_eval(code_get_child(node, no)));
}
Symbol* code_eval_child_symbol(const CodeNode* node, int no)
{
return code_get_symbol(code_eval(code_get_child(node, no)));
}
Define* code_eval_child_define(const CodeNode* node, int no)
{
return code_get_define(code_eval(code_get_child(node, no)));
}
const Bound* code_eval_child_bound(const CodeNode* node, int no)
{
return code_get_bound(code_eval(code_get_child(node, no)));
}
zimpl-3.3.6/src/zimpl/inst.h 0000644 0014172 0006025 00000042400 13304236715 015631 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: inst.h */
/* Name....: Instruction Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _INST_H_
#define _INST_H_
#ifdef __cplusplus
extern "C" {
#endif
#define INST_NULL ((Inst)0)
/* ??? */
extern CodeNode* i_expr_sin(CodeNode* self);
extern CodeNode* i_expr_cos(CodeNode* self);
extern CodeNode* i_expr_tan(CodeNode* self);
extern CodeNode* i_expr_asin(CodeNode* self);
extern CodeNode* i_expr_acos(CodeNode* self);
extern CodeNode* i_expr_atan(CodeNode* self);
/* inst.c
*/
/*lint -sem( i_bool_and, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_and(CodeNode* self);
/*lint -sem( i_bool_eq, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_eq(CodeNode* self);
/*lint -sem( i_bool_exists, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_exists(CodeNode* self);
/*lint -sem( i_bool_false, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_false(CodeNode* self);
/*lint -sem( i_bool_ge, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_ge(CodeNode* self);
/*lint -sem( i_bool_gt, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_gt(CodeNode* self);
/*lint -sem( i_bool_is_elem, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_is_elem(CodeNode* self);
/*lint -sem( i_bool_le, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_le(CodeNode* self);
/*lint -sem( i_bool_lt, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_lt(CodeNode* self);
/*lint -sem( i_bool_ne, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_ne(CodeNode* self);
/*lint -sem( i_bool_not, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_not(CodeNode* self);
/*lint -sem( i_bool_or, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_or(CodeNode* self);
/*lint -sem( i_bool_seq, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_seq(CodeNode* self);
/*lint -sem( i_bool_sneq, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_sneq(CodeNode* self);
/*lint -sem( i_bool_sseq, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_sseq(CodeNode* self);
/*lint -sem( i_bool_subs, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_subs(CodeNode* self);
/*lint -sem( i_bool_true, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_true(CodeNode* self);
/*lint -sem( i_bool_xor, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bool_xor(CodeNode* self);
/*lint -sem( i_bound_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_bound_new(CodeNode* self);
/*lint -sem( i_check, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_check(CodeNode* self);
/*lint -sem( i_constraint_list, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_constraint_list(CodeNode* self);
/*lint -sem( i_constraint, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_constraint(CodeNode* self);
/*lint -sem( i_rangeconst, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_rangeconst(CodeNode* self);
/*lint -sem( i_elem_list_add, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_elem_list_add(CodeNode* self);
/*lint -sem( i_elem_list_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_elem_list_new(CodeNode* self);
/*lint -sem( i_entry, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_entry(CodeNode* self);
/*lint -sem( i_entry_list_add, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_entry_list_add(CodeNode* self);
/*lint -sem( i_entry_list_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_entry_list_new(CodeNode* self);
/*lint -sem( i_entry_list_powerset, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_entry_list_powerset(CodeNode* self);
/*lint -sem( i_entry_list_subsets, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_entry_list_subsets(CodeNode* self);
/*lint -sem( i_expr_abs, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_abs(CodeNode* self);
/*lint -sem( i_expr_sgn, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_sgn(CodeNode* self);
/*lint -sem( i_expr_add, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_add(CodeNode* self);
/*lint -sem( i_expr_card, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_card(CodeNode* self);
/*lint -sem( i_expr_ceil, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_ceil(CodeNode* self);
/*lint -sem( i_expr_div, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_div(CodeNode* self);
/*lint -sem( i_expr_exp, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_exp(CodeNode* self);
/*lint -sem( i_expr_sqrt, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_sqrt(CodeNode* self);
/*lint -sem( i_expr_fac, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_fac(CodeNode* self);
/*lint -sem( i_expr_floor, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_floor(CodeNode* self);
/*lint -sem( i_expr_if_else, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_if_else(CodeNode* self);
/*lint -sem( i_expr_intdiv, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_intdiv(CodeNode* self);
/*lint -sem( i_expr_length, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_length(CodeNode* self);
/*lint -sem( i_expr_ln, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_ln(CodeNode* self);
/*lint -sem( i_expr_log, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_log(CodeNode* self);
/*lint -sem( i_expr_ord, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_ord(CodeNode* self);
/*lint -sem( i_expr_prod, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_prod(CodeNode* self);
/*lint -sem( i_expr_rand, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_rand(CodeNode* self);
/*lint -sem( i_expr_round, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_round(CodeNode* self);
/*lint -sem( i_expr_sum, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_sum(CodeNode* self);
/*lint -sem( i_expr_max, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_max(CodeNode* self);
/*lint -sem( i_expr_max2, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_max2(CodeNode* self);
/*lint -sem( i_expr_sglmax, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_sglmax(CodeNode* self);
/*lint -sem( i_expr_min, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_min(CodeNode* self);
/*lint -sem( i_expr_min2, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_min2(CodeNode* self);
/*lint -sem( i_expr_sglmin, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_sglmin(CodeNode* self);
/*lint -sem( i_expr_mul, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_mul(CodeNode* self);
/*lint -sem( i_expr_mod, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_mod(CodeNode* self);
/*lint -sem( i_expr_neg, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_neg(CodeNode* self);
/*lint -sem( i_expr_pow, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_pow(CodeNode* self);
/*lint -sem( i_expr_sub, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_sub(CodeNode* self);
/*lint -sem( i_expr_substr, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_expr_substr(CodeNode* self);
/*lint -sem( i_forall, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_forall(CodeNode* self);
/*lint -sem( i_idxset_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_idxset_new(CodeNode* self);
/*lint -sem( i_idxset_pseudo_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_idxset_pseudo_new(CodeNode* self);
/*lint -sem( i_list_matrix, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_list_matrix(CodeNode* self);
/*lint -sem( i_local_deref, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_local_deref(CodeNode* self);
/*lint -sem( i_matrix_list_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_matrix_list_new(CodeNode* self);
/*lint -sem( i_matrix_list_add, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_matrix_list_add(CodeNode* self);
/*lint -sem( i_newdef, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_newdef(CodeNode* self);
/*lint -sem( i_newsym_para1, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_newsym_para1(CodeNode* self);
/*lint -sem( i_newsym_para2, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_newsym_para2(CodeNode* self);
/*lint -sem( i_newsym_set1, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_newsym_set1(CodeNode* self);
/*lint -sem( i_newsym_set2, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_newsym_set2(CodeNode* self);
/*lint -sem( i_newsym_var, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_newsym_var(CodeNode* self);
/*lint -sem( i_nop, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_nop(CodeNode* self);
/*lint -sem( i_object_max, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_object_max(CodeNode* self);
/*lint -sem( i_object_min, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_object_min(CodeNode* self);
/*lint -sem( i_print, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_print(CodeNode* self);
/*lint -sem( i_set_argmax, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_argmax(CodeNode* self);
/*lint -sem( i_set_argmin, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_argmin(CodeNode* self);
/*lint -sem( i_set_cross, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_cross(CodeNode* self);
/*lint -sem( i_set_empty, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_empty(CodeNode* self);
/*lint -sem( i_set_expr, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_expr(CodeNode* self);
/*lint -sem( i_set_idxset, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_idxset(CodeNode* self);
/*lint -sem( i_set_indexset, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_indexset(CodeNode* self);
/*lint -sem( i_set_inter, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_inter(CodeNode* self);
/*lint -sem( i_set_inter2, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_inter2(CodeNode* self);
/*lint -sem( i_set_minus, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_minus(CodeNode* self);
/*lint -sem( i_set_new_tuple, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_new_tuple(CodeNode* self);
/*lint -sem( i_set_new_elem, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_new_elem(CodeNode* self);
/*lint -sem( i_set_proj, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_proj(CodeNode* self);
/*lint -sem( i_set_pseudo, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_pseudo(CodeNode* self);
/*lint -sem( i_set_range, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_range(CodeNode* self);
/*lint -sem( i_set_range2, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_range2(CodeNode* self);
/*lint -sem( i_set_sdiff, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_sdiff(CodeNode* self);
/*lint -sem( i_set_union, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_union(CodeNode* self);
/*lint -sem( i_set_union2, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_set_union2(CodeNode* self);
/*lint -sem( i_sos, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_sos(CodeNode* self);
/*lint -sem( i_soset, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_soset(CodeNode* self);
/*lint -sem( i_subto, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_subto(CodeNode* self);
/*lint -sem( i_symbol_deref, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_symbol_deref(CodeNode* self);
/*lint -sem( i_define_deref, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_define_deref(CodeNode* self);
/*lint -sem( i_term_add, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_term_add(CodeNode* self);
/*lint -sem( i_term_coeff, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_term_coeff(CodeNode* self);
/*lint -sem( i_term_const, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_term_const(CodeNode* self);
/*lint -sem( i_term_expr, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_term_expr(CodeNode* self);
/*lint -sem( i_term_mul, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_term_mul(CodeNode* self);
/*lint -sem( i_term_quadratic, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_term_power(CodeNode* self);
/*lint -sem( i_term_power, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_term_sub(CodeNode* self);
/*lint -sem( i_term_sum, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_term_sum(CodeNode* self);
/*lint -sem( i_tuple_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_tuple_new(CodeNode* self);
/*lint -sem( i_tuple_empty, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_tuple_empty(CodeNode* self);
/*lint -sem( i_tuple_list_add, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_tuple_list_add(CodeNode* self);
/*lint -sem( i_tuple_list_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_tuple_list_new(CodeNode* self);
/* iread.c
*/
/*lint -sem( i_read_new, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_read_new(CodeNode* self);
/*lint -sem( i_read_param, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_read_param(CodeNode* self);
/*lint -sem( i_read_comment, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_read_comment(CodeNode* self);
/*lint -sem( i_read_match, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_read_match(CodeNode* self);
/*lint -sem( i_read_use, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_read_use(CodeNode* self);
/*lint -sem( i_read_skip, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_read_skip(CodeNode* self);
/*lint -sem( i_read, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_read(CodeNode* self);
/* vinst.c
*/
/*lint -sem( i_vabs, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vabs(CodeNode* self);
/*lint -sem( i_vbool_and, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_and(CodeNode* self);
/*lint -sem( i_vbool_eq, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_eq(CodeNode* self);
/*lint -sem( i_vbool_ne, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_ne(CodeNode* self);
/*lint -sem( i_vbool_ge, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_ge(CodeNode* self);
/*lint -sem( i_vbool_gt, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_gt(CodeNode* self);
/*lint -sem( i_vbool_le, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_le(CodeNode* self);
/*lint -sem( i_vbool_lt, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_lt(CodeNode* self);
/*lint -sem( i_vbool_not, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_not(CodeNode* self);
/*lint -sem( i_vbool_or, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_or(CodeNode* self);
/*lint -sem( i_vbool_xor, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vbool_xor(CodeNode* self);
/*lint -sem( i_vexpr_fun, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vexpr_fun(CodeNode* self);
/*lint -sem( i_vif, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vif(CodeNode* self);
/*lint -sem( i_vif_else, 1p == 1, type(1), @P > malloc(1P)p) */
extern CodeNode* i_vif_else(CodeNode* self);
#ifdef __cplusplus
}
#endif
#endif /* _INST_H_ */
zimpl-3.3.6/src/zimpl/vinst.c 0000644 0014172 0006025 00000111630 13304236715 016014 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: vinst.c */
/* Name....: Variable Instructions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
/* #define TRACE 1 */
#include "zimpl/lint.h"
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/define.h"
#include "zimpl/bound.h"
#include "zimpl/idxset.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/rdefpar.h"
#include "zimpl/conname.h"
#include "zimpl/stmt.h"
#include "zimpl/prog.h"
#include "zimpl/local.h"
#include "zimpl/list.h"
#include "zimpl/entry.h"
#include "zimpl/heap.h"
#include "zimpl/code.h"
#include "zimpl/inst.h"
#include "zimpl/xlpglue.h"
#include "zimpl/strstore.h"
enum vbool_cmp_operator { VBOOL_LT, VBOOL_LE, VBOOL_EQ, VBOOL_NE, VBOOL_GE, VBOOL_GT };
enum vbool_fixed_result { VBOOL_TRUE, VBOOL_FALSE, VBOOL_OPEN };
typedef enum vbool_cmp_operator VBCmpOp;
typedef enum vbool_fixed_result VBFixed;
static int internal_vars = 0;
static int internal_cons = 0;
void interns_init()
{
assert(internal_vars == 0);
assert(internal_cons == 0);
}
void interns_exit()
{
internal_vars = 0;
internal_cons = 0;
}
static void create_new_constraint(
const char* basename,
const char* extension,
Term* term,
ConType con_type,
const Numb* lrhs,
unsigned int flags)
{
char* cname;
Trace("create_new_constraint");
assert(basename != NULL);
assert(extension != NULL);
assert(con_type != CON_RANGE);
assert(term_is_valid(term));
assert(numb_is_valid(lrhs));
cname = malloc(strlen(basename) + strlen(extension) + 10 + 1);
sprintf(cname, "%s%s_%d", basename, extension, internal_cons++);
(void)xlp_addcon_term(prog_get_lp(), cname, con_type, lrhs, lrhs, flags, term);
term_free(term);
free(cname);
}
static Entry* create_new_var_entry(
const char* basename,
const char* extension,
VarClass var_class,
const Bound* lower,
const Bound* upper)
{
char* vname;
Tuple* tuple;
Entry* entry;
Var* var;
Trace("create_new_var_entry");
assert(basename != NULL);
assert(extension != NULL);
/* assert(var_class != VAR_CON);*/
assert(bound_is_valid(lower));
assert(bound_is_valid(upper));
vname = malloc(strlen(basename) + strlen(extension) + strlen(SYMBOL_NAME_INTERNAL) + 16);
sprintf(vname, "%s%s%s_%d", SYMBOL_NAME_INTERNAL, basename, extension, internal_vars++);
var = xlp_addvar(prog_get_lp(), vname, var_class, lower, upper, numb_zero(), numb_zero());
tuple = tuple_new(1);
tuple_set_elem(tuple, 0, elem_new_strg(str_new(vname + strlen(SYMBOL_NAME_INTERNAL))));
entry = entry_new_var(tuple, var);
tuple_free(tuple);
free(vname);
return entry;
}
static VBFixed check_how_fixed(
VBCmpOp cmp_op,
const Numb* rhs)
{
VBFixed result = VBOOL_FALSE;
switch(cmp_op)
{
case VBOOL_EQ :
if (numb_equal(rhs, numb_zero()))
result = VBOOL_TRUE;
break;
case VBOOL_NE :
if (!numb_equal(rhs, numb_zero()))
result = VBOOL_TRUE;
break;
case VBOOL_LE :
if (numb_cmp(numb_zero(), rhs) <= 0)
result = VBOOL_TRUE;
break;
case VBOOL_GE :
if (numb_cmp(numb_zero(), rhs) >= 0)
result = VBOOL_TRUE;
break;
case VBOOL_LT :
if (numb_cmp(numb_zero(), rhs) < 0)
result = VBOOL_TRUE;
break;
case VBOOL_GT :
if (numb_cmp(numb_zero(), rhs) > 0)
result = VBOOL_TRUE;
break;
default :
abort();
}
return result;
}
static VBFixed check_if_fixed(
VBCmpOp cmp_op,
const Numb* lower,
const Numb* upper)
{
VBFixed result = VBOOL_OPEN;
/* lower <= upper
*/
assert(numb_cmp(lower, upper) <= 0);
switch(cmp_op)
{
case VBOOL_EQ :
if ( (numb_cmp(lower, numb_zero()) > 0)
|| (numb_cmp(upper, numb_zero()) < 0))
result = VBOOL_FALSE;
else
{
if (numb_equal(lower, upper))
{
assert(numb_equal(lower, numb_zero()));
assert(numb_equal(upper, numb_zero()));
result = VBOOL_TRUE;
}
}
break;
case VBOOL_NE :
if ( (numb_cmp(lower, numb_zero()) > 0)
|| (numb_cmp(upper, numb_zero()) < 0))
result = VBOOL_TRUE;
else
{
if (numb_equal(lower, upper))
{
assert(numb_equal(lower, numb_zero()));
assert(numb_equal(upper, numb_zero()));
result = VBOOL_FALSE;
}
}
break;
case VBOOL_LE :
if (numb_cmp(upper, numb_zero()) <= 0)
result = VBOOL_TRUE;
else if (numb_cmp(lower, numb_zero()) > 0)
result = VBOOL_FALSE;
break;
case VBOOL_GE :
if (numb_cmp(lower, numb_zero()) >= 0)
result = VBOOL_TRUE;
else if (numb_cmp(upper, numb_zero()) < 0)
result = VBOOL_FALSE;
break;
case VBOOL_LT :
if (numb_cmp(upper, numb_zero()) < 0)
result = VBOOL_TRUE;
else if (numb_cmp(lower, numb_zero()) >= 0)
result = VBOOL_FALSE;
break;
case VBOOL_GT :
if (numb_cmp(lower, numb_zero()) > 0)
result = VBOOL_TRUE;
else if (numb_cmp(upper, numb_zero()) <= 0)
result = VBOOL_FALSE;
break;
default :
abort();
}
return result;
}
static CodeNode* handle_vbool_cmp(CodeNode* self, VBCmpOp cmp_op)
{
Symbol* sym;
Term* term;
const Term* term_lhs;
const Term* term_rhs;
Numb* rhs;
unsigned int flags;
const char* cname;
Bound* lower;
Bound* upper;
Bound* bound_zero;
Bound* bound_one;
Entry* entry_result;
VBFixed fixed = VBOOL_OPEN;
Trace("handle_vbool_cmp");
assert(code_is_valid(self));
term_lhs = code_eval_child_term(self, 0);
term_rhs = code_eval_child_term(self, 1);
flags = 0;
rhs = numb_new_sub(term_get_constant(term_rhs), term_get_constant(term_lhs));
term = term_sub_term(term_lhs, term_rhs);
if (!term_is_all_integer(term))
{
fprintf(stderr, "*** Error 177: Boolean constraint not all integer\n");
code_errmsg(code_get_child(self, 0));
zpl_exit(EXIT_FAILURE);
}
/* Symbol for internal entries
*/
sym = symbol_lookup(SYMBOL_NAME_INTERNAL);
assert(sym != NULL);
cname = conname_get();
bound_zero = bound_new(BOUND_VALUE, numb_zero());
bound_one = bound_new(BOUND_VALUE, numb_one());
lower = term_get_lower_bound(term);
upper = term_get_upper_bound(term);
if (bound_get_type(lower) != BOUND_VALUE || bound_get_type(upper) != BOUND_VALUE)
{
fprintf(stderr, "*** Error 185: Term in Boolean constraint not bounded\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
/* Check if trival infeasible
*/
if (term_get_elements(term) == 0)
{
if (stmt_trigger_warning(176))
{
fprintf(stderr, "--- Warning 176: Empty LHS, in Boolean constraint\n");
code_errmsg(code_get_child(self, 0));
}
fixed = check_how_fixed(cmp_op, rhs);
assert(fixed != VBOOL_OPEN);
}
else
{
fixed = check_if_fixed(cmp_op, bound_get_value(lower), bound_get_value(upper));
}
if (fixed != VBOOL_OPEN)
{
if (fixed == VBOOL_TRUE)
entry_result = create_new_var_entry(cname, "_re", VAR_INT, bound_one, bound_one);
else
{
assert(fixed == VBOOL_FALSE);
entry_result = create_new_var_entry(cname, "_re", VAR_INT, bound_zero, bound_zero);
}
if (stmt_trigger_warning(178))
{
fprintf(stderr,
"--- Warning 178: Conditional always true or false due to bounds\n");
code_errmsg(code_get_child(self, 0)); /* pos of warning message */
}
term_free(term);
}
else
{
Entry* entry_xplus;
Entry* entry_xminus;
Entry* entry_bplus;
Entry* entry_bminus;
/* Remove constant from term
*/
term_add_constant(term, rhs);
if (numb_cmp(bound_get_value(lower), numb_zero()) < 0)
{
Numb* numb = numb_copy(bound_get_value(lower));
numb_abs(numb);
bound_free(lower);
lower = bound_new(BOUND_VALUE, numb);
numb_free(numb);
}
else
{
bound_free(lower);
lower = bound_new(BOUND_VALUE, numb_zero());
}
if (numb_cmp(bound_get_value(upper), numb_zero()) < 0)
{
bound_free(upper);
upper = bound_new(BOUND_VALUE, numb_zero());
}
/* Create x^+, x^-, b^+, b^-, Result
*/
entry_xplus = create_new_var_entry(cname, "_xp", VAR_INT, bound_zero, upper);
entry_xminus = create_new_var_entry(cname, "_xm", VAR_INT, bound_zero, lower);
entry_bplus = create_new_var_entry(cname, "_bp", VAR_INT, bound_zero, bound_one);
entry_bminus = create_new_var_entry(cname, "_bm", VAR_INT, bound_zero, bound_one);
entry_result = create_new_var_entry(cname, "_re", VAR_INT, bound_zero, bound_one);
/* add term = x^+ + x^-
*/
term_add_elem(term, entry_xplus, numb_minusone(), MFUN_NONE);
term_add_elem(term, entry_xminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_a", term, CON_EQUAL, rhs, flags);
/* bplus <= xplus */
term = term_new(2);
term_add_elem(term, entry_bplus, numb_one(), MFUN_NONE);
term_add_elem(term, entry_xplus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_b", term, CON_RHS, numb_zero(), flags);
/* bminus <= xminus */
term = term_new(2);
term_add_elem(term, entry_bminus, numb_one(), MFUN_NONE);
term_add_elem(term, entry_xminus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_c", term, CON_RHS, numb_zero(), flags);
/* bplus * upper >= xplus */
term = term_new(2);
if (!numb_equal(bound_get_value(upper), numb_zero()))
term_add_elem(term, entry_bplus, bound_get_value(upper), MFUN_NONE);
term_add_elem(term, entry_xplus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_d", term, CON_LHS, numb_zero(), flags);
/* bminus * lower >= xminus */
term = term_new(2);
if (!numb_equal(bound_get_value(lower), numb_zero()))
term_add_elem(term, entry_bminus, bound_get_value(lower), MFUN_NONE);
term_add_elem(term, entry_xminus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_e", term, CON_LHS, numb_zero(), flags);
switch(cmp_op)
{
case VBOOL_EQ :
/* 1 - result = bplus + bminus => result + bplus + bminus = 1 */
term = term_new(3);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bplus, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_f", term, CON_EQUAL, numb_one(), flags);
break;
case VBOOL_NE :
/* result = bplus + bminus => result - bplus - bminus = 0*/
term = term_new(3);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bplus, numb_minusone(), MFUN_NONE);
term_add_elem(term, entry_bminus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_f", term, CON_EQUAL, numb_zero(), flags);
break;
case VBOOL_LE :
/* bplus + bminus <= 1,
* result = 1 - bplus => result + bplus = 1
*/
term = term_new(2);
term_add_elem(term, entry_bplus, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_f", term, CON_RHS, numb_one(), flags);
term = term_new(2);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bplus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_g", term, CON_EQUAL, numb_one(), flags);
break;
case VBOOL_GE :
/* bplus + bminus <= 1,
* result = 1 - bminus => result + bminus = 1
*/
term = term_new(2);
term_add_elem(term, entry_bplus, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_f", term, CON_RHS, numb_one(), flags);
term = term_new(2);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_g", term, CON_EQUAL, numb_one(), flags);
break;
case VBOOL_LT :
/* bplus + bminus <= 1,
* result = bminus => result - bminus = 0
*/
term = term_new(2);
term_add_elem(term, entry_bplus, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_f", term, CON_RHS, numb_one(), flags);
/* This is somewhat superflous
*/
term = term_new(2);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bminus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_g", term, CON_EQUAL, numb_zero(), flags);
break;
case VBOOL_GT :
/* bplus + bminus <= 1,
* result = bplus => result - bplus = 0
*/
term = term_new(2);
term_add_elem(term, entry_bplus, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_f", term, CON_RHS, numb_one(), flags);
/* This is somewhat superflous
*/
term = term_new(2);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
term_add_elem(term, entry_bplus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_g", term, CON_EQUAL, numb_zero(), flags);
break;
default :
abort();
}
symbol_add_entry(sym, entry_xplus);
symbol_add_entry(sym, entry_xminus);
symbol_add_entry(sym, entry_bplus);
symbol_add_entry(sym, entry_bminus);
}
term = term_new(1);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
code_value_term(self, term);
symbol_add_entry(sym, entry_result);
bound_free(bound_one);
bound_free(bound_zero);
bound_free(lower);
bound_free(upper);
numb_free(rhs);
return self;
}
CodeNode* i_vbool_ne(CodeNode* self)
{
Trace("i_vbool_ne");
return handle_vbool_cmp(self, VBOOL_NE);
}
CodeNode* i_vbool_eq(CodeNode* self)
{
Trace("i_vbool_eq");
return handle_vbool_cmp(self, VBOOL_EQ);
}
CodeNode* i_vbool_lt(CodeNode* self)
{
Trace("i_vbool_lt");
return handle_vbool_cmp(self, VBOOL_LT);
}
CodeNode* i_vbool_le(CodeNode* self)
{
Trace("i_vbool_le");
return handle_vbool_cmp(self, VBOOL_LE);
}
CodeNode* i_vbool_gt(CodeNode* self)
{
Trace("i_vbool_gt");
return handle_vbool_cmp(self, VBOOL_GT);
}
CodeNode* i_vbool_ge(CodeNode* self)
{
Trace("i_vbool_ge");
return handle_vbool_cmp(self, VBOOL_GE);
}
CodeNode* i_vbool_and(CodeNode* self)
{
const Term* term_a;
const Term* term_b;
const char* cname;
Term* term;
Bound* bound_zero;
Bound* bound_one;
Entry* entry_result;
unsigned int flags = 0;
Symbol* sym;
Trace("i_vbool_and");
cname = conname_get();
bound_zero = bound_new(BOUND_VALUE, numb_zero());
bound_one = bound_new(BOUND_VALUE, numb_one());
term_a = code_eval_child_term(self, 0);
term_b = code_eval_child_term(self, 1);
assert(term_get_elements(term_a) == 1);
assert(term_get_elements(term_b) == 1);
entry_result = create_new_var_entry(cname, "_re", VAR_INT, bound_zero, bound_one);
/* ------------------------------------- */
/* a - re >= 0 */
term = term_copy(term_a);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_a", term, CON_LHS, numb_zero(), flags);
/* b - re >= 0 */
term = term_copy(term_b);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_b", term, CON_LHS, numb_zero(), flags);
/* a + b - re <= 1 */
term = term_add_term(term_a, term_b);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_c", term, CON_RHS, numb_one(), flags);
/* ------------------------------------- */
term = term_new(1);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
code_value_term(self, term);
/* Symbol for internal entries
*/
sym = symbol_lookup(SYMBOL_NAME_INTERNAL);
assert(sym != NULL);
symbol_add_entry(sym, entry_result);
bound_free(bound_zero);
bound_free(bound_one);
return self;
}
CodeNode* i_vbool_or(CodeNode* self)
{
const Term* term_a;
const Term* term_b;
const char* cname;
Term* term;
Bound* bound_zero;
Bound* bound_one;
Entry* entry_result;
unsigned int flags = 0;
Symbol* sym;
Trace("i_vbool_or");
cname = conname_get();
bound_zero = bound_new(BOUND_VALUE, numb_zero());
bound_one = bound_new(BOUND_VALUE, numb_one());
term_a = code_eval_child_term(self, 0);
term_b = code_eval_child_term(self, 1);
assert(term_get_elements(term_a) == 1);
assert(term_get_elements(term_b) == 1);
entry_result = create_new_var_entry(cname, "_re", VAR_INT, bound_zero, bound_one);
/* ------------------------------------- */
/* a - re <= 0 */
term = term_copy(term_a);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_a", term, CON_RHS, numb_zero(), flags);
/* b - re <= 0 */
term = term_copy(term_b);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_b", term, CON_RHS, numb_zero(), flags);
/* a + b - re >= 0 */
term = term_add_term(term_a, term_b);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_c", term, CON_LHS, numb_zero(), flags);
/* ------------------------------------- */
term = term_new(1);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
code_value_term(self, term);
/* Symbol for internal entries
*/
sym = symbol_lookup(SYMBOL_NAME_INTERNAL);
assert(sym != NULL);
symbol_add_entry(sym, entry_result);
bound_free(bound_zero);
bound_free(bound_one);
return self;
}
CodeNode* i_vbool_xor(CodeNode* self)
{
const Term* term_a;
const Term* term_b;
const char* cname;
Term* term;
Bound* bound_zero;
Bound* bound_one;
Entry* entry_result;
unsigned int flags = 0;
Symbol* sym;
Numb* numb;
Trace("i_vbool_xor");
cname = conname_get();
bound_zero = bound_new(BOUND_VALUE, numb_zero());
bound_one = bound_new(BOUND_VALUE, numb_one());
term_a = code_eval_child_term(self, 0);
term_b = code_eval_child_term(self, 1);
assert(term_get_elements(term_a) == 1);
assert(term_get_elements(term_b) == 1);
entry_result = create_new_var_entry(cname, "_re", VAR_INT, bound_zero, bound_one);
/* ------------------------------------- */
/* a + b - re >= 0 */
term = term_add_term(term_a, term_b);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_a", term, CON_LHS, numb_zero(), flags);
/* a - b - re <= 0 */
term = term_sub_term(term_a, term_b);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_b", term, CON_RHS, numb_zero(), flags);
/* a - b + re >= 0 */
term = term_sub_term(term_a, term_b);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_c", term, CON_LHS, numb_zero(), flags);
/* a + b + re <= 2 */
numb = numb_new_integer(2);
term = term_add_term(term_a, term_b);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_d", term, CON_RHS, numb, flags);
numb_free(numb);
/* ------------------------------------- */
term = term_new(1);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
code_value_term(self, term);
/* Symbol for internal entries
*/
sym = symbol_lookup(SYMBOL_NAME_INTERNAL);
assert(sym != NULL);
symbol_add_entry(sym, entry_result);
bound_free(bound_zero);
bound_free(bound_one);
return self;
}
CodeNode* i_vbool_not(CodeNode* self)
{
const Term* term_a;
const char* cname;
Term* term;
Bound* bound_zero;
Bound* bound_one;
Entry* entry_result;
unsigned int flags = 0;
Symbol* sym;
Trace("i_vbool_not");
cname = conname_get();
bound_zero = bound_new(BOUND_VALUE, numb_zero());
bound_one = bound_new(BOUND_VALUE, numb_one());
term_a = code_eval_child_term(self, 0);
assert(term_get_elements(term_a) == 1);
entry_result = create_new_var_entry(cname, "_re", VAR_INT, bound_zero, bound_one);
/* ------------------------------------- */
/* a + re == 1 */
term = term_copy(term_a);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_a", term, CON_EQUAL, numb_one(), flags);
/* ------------------------------------- */
term = term_new(1);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
code_value_term(self, term);
/* Symbol for internal entries
*/
sym = symbol_lookup(SYMBOL_NAME_INTERNAL);
assert(sym != NULL);
symbol_add_entry(sym, entry_result);
bound_free(bound_zero);
bound_free(bound_one);
return self;
}
static void generate_conditional_constraint(
const CodeNode* self,
const Term* vif_term,
const Term* lhs_term,
ConType con_type,
const Numb* rhs,
unsigned int flags,
bool then_case)
{
Bound* bound;
const Numb* bound_val;
Trace("generate_conditional_constraint");
assert(con_type == CON_RHS || con_type == CON_LHS);
bound = (con_type == CON_RHS)
? term_get_upper_bound(lhs_term)
: term_get_lower_bound(lhs_term);
if (bound_get_type(bound) != BOUND_VALUE)
{
fprintf(stderr, "*** Error 179: Conditional only possible on bounded constraints\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
bound_val = bound_get_value(bound);
if ( (con_type == CON_RHS && numb_cmp(bound_val, rhs) <= 0)
|| (con_type == CON_LHS && numb_cmp(bound_val, rhs) >= 0))
{
/* ??? This can be triggered for an eqiality constraint if after the
* split one part is always true.
*/
if (stmt_trigger_warning(180))
{
fprintf(stderr, "--- Warning 180: Conditional constraint always true due to bounds\n");
code_errmsg(self);
}
}
else
{
const char* basename = conname_get();
char* cname = malloc(strlen(basename) + 5);
Term* big_term = term_copy(vif_term);
Numb* big_m = then_case ? numb_new_sub(bound_val, rhs) : numb_new_sub(rhs, bound_val);
const Numb* new_rhs = then_case ? bound_val : rhs;
term_mul_coeff(big_term, big_m);
term_append_term(big_term, lhs_term);
sprintf(cname, "%s_%c_%c", basename,
then_case ? 't' : 'e',
con_type == CON_RHS ? 'r' : 'l');
(void)xlp_addcon_term(prog_get_lp(), cname, con_type, new_rhs, new_rhs, flags, big_term);
numb_free(big_m);
term_free(big_term);
free(cname);
}
bound_free(bound);
}
/*ARGSUSED*/
static void generate_indicator_constraint(
UNUSED const CodeNode* self,
const Term* vif_term,
const Term* lhs_term,
ConType con_type,
const Numb* rhs,
unsigned int flags,
bool then_case)
{
Numb* lhs;
Term* ind_term;
const char* basename;
char* cname;
Trace("generate_indicator_constraint");
assert(flags & LP_FLAG_CON_INDIC);
ind_term = term_make_conditional(vif_term, lhs_term, then_case);
basename = conname_get();
cname = malloc(strlen(basename) + 5);
sprintf(cname, "%s_%c", basename, then_case ? 't' : 'f');
/* CON_EQUAL -> lhs == rhs
* CON_RHS -> lhs == rhs, lhs does not matter
* CON_LHS -> lhs == rhs, rhs does not matter
* CON_RANGE -> not allowed
*/
lhs = numb_copy(rhs);
#if 0
if (con_type == CON_LHS)
numb_neg(lhs);
#endif
(void)xlp_addcon_term(prog_get_lp(), cname, con_type, lhs, rhs, flags, ind_term);
term_free(ind_term);
numb_free(lhs);
free(cname);
}
static void handle_vif_then_else(
const CodeNode* self,
const Term* vif_term,
const Term* lhs_term,
ConType con_type,
const Term* rhs_term,
unsigned int flags,
bool then_case)
{
Term* term;
Numb* rhs;
Trace("handle_vif_then_else");
rhs = numb_new_sub(term_get_constant(rhs_term), term_get_constant(lhs_term));
term = term_sub_term(lhs_term, rhs_term);
term_add_constant(term, rhs);
/* Check if trival infeasible
*/
if (term_get_elements(term) == 0)
{
fprintf(stderr, "*** Error 181: Empty LHS, not allowed in conditional constraint\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
assert(con_type == CON_RHS || con_type == CON_LHS || con_type == CON_EQUAL);
if (!term_is_linear(term))
{
fprintf(stderr, "*** Error 222: Term inside a then or else constraint not linear\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
if (flags & LP_FLAG_CON_INDIC)
generate_indicator_constraint(self, vif_term, term, con_type, rhs, flags, then_case);
else
{
/* <=, ==
*/
if (con_type == CON_RHS || con_type == CON_EQUAL)
generate_conditional_constraint(self, vif_term, term, CON_RHS, rhs, flags, then_case);
/* >=, ==
*/
if (con_type == CON_LHS || con_type == CON_EQUAL)
generate_conditional_constraint(self, vif_term, term, CON_LHS, rhs, flags, then_case);
}
numb_free(rhs);
term_free(term);
}
CodeNode* i_vif_else(CodeNode* self)
{
const Term* vif_term;
const Term* lhs_term;
const Term* rhs_term;
ConType con_type;
unsigned int flags;
Trace("i_vif_else");
assert(code_is_valid(self));
vif_term = code_eval_child_term(self, 0);
flags = code_eval_child_bits(self, 7);
lhs_term = code_eval_child_term(self, 1);
con_type = code_eval_child_contype(self, 2);
rhs_term = code_eval_child_term(self, 3);
handle_vif_then_else(code_get_child(self, 1), /* pos for error messages */
vif_term, lhs_term, con_type, rhs_term, flags, true);
lhs_term = code_eval_child_term(self, 4);
con_type = code_eval_child_contype(self, 5);
rhs_term = code_eval_child_term(self, 6);
handle_vif_then_else(code_get_child(self, 4), /* pos for error messages */
vif_term, lhs_term, con_type, rhs_term, flags, false);
code_value_void(self);
conname_next();
return self;
}
CodeNode* i_vif(CodeNode* self)
{
const Term* vif_term;
const Term* lhs_term;
const Term* rhs_term;
ConType con_type;
unsigned int flags;
Trace("i_vif");
assert(code_is_valid(self));
vif_term = code_eval_child_term(self, 0);
lhs_term = code_eval_child_term(self, 1);
con_type = code_eval_child_contype(self, 2);
rhs_term = code_eval_child_term(self, 3);
flags = code_eval_child_bits(self, 4);
handle_vif_then_else(code_get_child(self, 1), /* pos for error messages */
vif_term, lhs_term, con_type, rhs_term, flags, true);
code_value_void(self);
conname_next();
return self;
}
CodeNode* i_vabs(CodeNode* self)
{
Symbol* sym;
Term* term;
const Term* term_abs;
Numb* rhs;
unsigned int flags = 0;
const char* cname;
Bound* lower;
Bound* upper;
const Bound* bigger;
Bound* bound_zero;
Bound* bound_one;
Entry* entry_xplus;
Entry* entry_xminus;
Entry* entry_bplus;
Entry* entry_result;
Trace("i_vabs");
assert(code_is_valid(self));
term_abs = code_eval_child_term(self, 0);
rhs = numb_copy(term_get_constant(term_abs));
term = term_copy(term_abs);
/* Check if trival infeasible
*/
if (term_get_elements(term) == 0)
{
fprintf(stderr, "*** Error 182: Empty LHS, in variable vabs\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
if (!term_is_all_integer(term))
{
fprintf(stderr, "*** Error 183: vabs term not all integer\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
cname = conname_get();
bound_zero = bound_new(BOUND_VALUE, numb_zero());
bound_one = bound_new(BOUND_VALUE, numb_one());
lower = term_get_lower_bound(term);
upper = term_get_upper_bound(term);
if (bound_get_type(lower) != BOUND_VALUE || bound_get_type(upper) != BOUND_VALUE)
{
fprintf(stderr, "*** Error 184: vabs term not bounded\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
numb_neg(rhs);
term_add_constant(term, rhs);
if (numb_cmp(bound_get_value(lower), numb_zero()) < 0)
{
Numb* numb = numb_copy(bound_get_value(lower));
numb_abs(numb);
bound_free(lower);
lower = bound_new(BOUND_VALUE, numb);
numb_free(numb);
}
else
{
bound_free(lower);
lower = bound_new(BOUND_VALUE, numb_zero());
}
if (numb_cmp(bound_get_value(upper), numb_zero()) < 0)
{
bound_free(upper);
upper = bound_new(BOUND_VALUE, numb_zero());
}
bigger = (numb_cmp(bound_get_value(lower), bound_get_value(upper)) > 0)
? lower : upper;
/* Create x^+, x^-, Result
*/
entry_xplus = create_new_var_entry(cname, "_xp", VAR_INT, bound_zero, upper);
entry_xminus = create_new_var_entry(cname, "_xm", VAR_INT, bound_zero, lower);
entry_bplus = create_new_var_entry(cname, "_bp", VAR_INT, bound_zero, bound_one);
entry_result = create_new_var_entry(cname, "_re", VAR_INT, bound_zero, bigger);
/* add term = x^+ + x^-
*/
term_add_elem(term, entry_xplus, numb_minusone(), MFUN_NONE);
term_add_elem(term, entry_xminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_a", term, CON_EQUAL, rhs, flags);
/* bplus * upper >= xplus */
term = term_new(2);
if (!numb_equal(bound_get_value(upper), numb_zero()))
term_add_elem(term, entry_bplus, bound_get_value(upper), MFUN_NONE);
term_add_elem(term, entry_xplus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_b", term, CON_LHS, numb_zero(), flags);
/* (1 - bplus) * lower >= xminus
* lower - bplus * lower - xminus >= 0
* - bplus * lower - xminus >= -lower
* xminus + bplus * lower <= lower
*/
term = term_new(2);
if (!numb_equal(bound_get_value(lower), numb_zero()))
term_add_elem(term, entry_bplus, bound_get_value(lower), MFUN_NONE);
term_add_elem(term, entry_xminus, numb_one(), MFUN_NONE);
create_new_constraint(cname, "_c", term, CON_RHS, bound_get_value(lower), flags);
/* result - xplus - xminus == 0
*/
term = term_new(3);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
term_add_elem(term, entry_xplus, numb_minusone(), MFUN_NONE);
term_add_elem(term, entry_xminus, numb_minusone(), MFUN_NONE);
create_new_constraint(cname, "_d", term, CON_EQUAL, numb_zero(), flags);
term = term_new(1);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
code_value_term(self, term);
/* Symbol for internal entries
*/
sym = symbol_lookup(SYMBOL_NAME_INTERNAL);
assert(sym != NULL);
symbol_add_entry(sym, entry_xplus);
symbol_add_entry(sym, entry_xminus);
symbol_add_entry(sym, entry_bplus);
symbol_add_entry(sym, entry_result);
bound_free(bound_one);
bound_free(bound_zero);
bound_free(lower);
bound_free(upper);
numb_free(rhs);
return self;
}
CodeNode* i_vexpr_fun(CodeNode* self)
{
Symbol* sym;
const Term* term_fun;
const char* cname;
const Numb* expo;
const Numb* funno;
unsigned int flags = 0;
Term* term;
Entry* entry_tmp;
Entry* entry_result;
Bound* t_lower;
Bound* t_upper;
Bound* r_lower;
Bound* r_upper;
MFun mfun;
Numb* rhs;
Trace("i_vexpr_fun");
/* r = result, t = temp
*
* r = f(vexpr)
* t = vexpr => vexpr - t == 0
* r = f(t) => f(t) - r == 0
*
* WARNING: The coefficent of a monom that is a function
* is used as the exponent for functions that need a second
* number argument, e.g. pow(x*y, 3)
*/
assert(code_is_valid(self));
funno = code_eval_child_numb(self, 0);
assert(numb_is_int(funno));
mfun = (MFun)numb_toint(funno);
term_fun = code_eval_child_term(self, 1);
switch(mfun)
{
case MFUN_SQRT :
t_lower = bound_new(BOUND_VALUE, numb_zero());
t_upper = bound_new(BOUND_INFTY, NULL);
r_lower = bound_new(BOUND_VALUE, numb_zero());
r_upper = bound_new(BOUND_INFTY, NULL);
break;
case MFUN_LOG :
case MFUN_LN :
t_lower = bound_new(BOUND_VALUE, numb_zero());
t_upper = bound_new(BOUND_INFTY, NULL);
r_lower = bound_new(BOUND_MINUS_INFTY, NULL);
r_upper = bound_new(BOUND_INFTY, NULL);
break;
case MFUN_EXP :
case MFUN_TAN :
case MFUN_POW :
case MFUN_SGNPOW :
t_lower = bound_new(BOUND_MINUS_INFTY, NULL);
t_upper = bound_new(BOUND_INFTY, NULL);
r_lower = bound_new(BOUND_MINUS_INFTY, NULL);
r_upper = bound_new(BOUND_INFTY, NULL);
break;
case MFUN_SIN :
case MFUN_COS :
case MFUN_SGN :
t_lower = bound_new(BOUND_MINUS_INFTY, NULL);
t_upper = bound_new(BOUND_INFTY, NULL);
r_lower = bound_new(BOUND_VALUE, numb_minusone());
r_upper = bound_new(BOUND_VALUE, numb_one());
break;
case MFUN_ABS :
t_lower = bound_new(BOUND_MINUS_INFTY, NULL);
t_upper = bound_new(BOUND_INFTY, NULL);
r_lower = bound_new(BOUND_VALUE, numb_zero());
r_upper = bound_new(BOUND_INFTY, NULL);
break;
default :
abort();
}
if (mfun == MFUN_POW || mfun == MFUN_SGNPOW)
expo = code_eval_child_numb(self, 2);
else
expo = numb_one();
cname = conname_get();
entry_tmp = create_new_var_entry(cname, "_t", VAR_CON, t_lower, t_upper);
entry_result = create_new_var_entry(cname, "_r", mfun == MFUN_SGN ? VAR_INT : VAR_CON, r_lower, r_upper);
/* vexpr - t == 0
*/
term = term_copy(term_fun);
term_add_elem(term, entry_tmp, numb_minusone(), MFUN_NONE);
rhs = numb_new_mul(term_get_constant(term), numb_minusone());
term_add_constant(term, rhs);
create_new_constraint(cname, "_a", term, CON_EQUAL, rhs, flags);
numb_free(rhs);
/* fun(t) - r == 0
*/
term = term_new(2);
term_add_elem(term, entry_result, numb_minusone(), MFUN_NONE);
term_add_elem(term, entry_tmp, expo, mfun);
create_new_constraint(cname, "_b", term, CON_EQUAL, numb_zero(), flags);
term = term_new(1);
term_add_elem(term, entry_result, numb_one(), MFUN_NONE);
code_value_term(self, term);
sym = symbol_lookup(SYMBOL_NAME_INTERNAL);
assert(sym != NULL);
symbol_add_entry(sym, entry_tmp);
symbol_add_entry(sym, entry_result);
bound_free(t_lower);
bound_free(t_upper);
bound_free(r_lower);
bound_free(r_upper);
return self;
}
zimpl-3.3.6/src/zimpl/strstore.h 0000644 0014172 0006025 00000003512 13304236715 016542 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: strstore2.c */
/* Name....: String Storage Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _STRSTORE_H_
#define _STRSTORE_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void str_init(void);
extern void str_exit(void);
/*lint -sem( str_new, 1p && nulterm(1), @p == 1p && nulterm(@)) */
extern const char* str_new(const char* s);
/*lint -sem( str_hash, 1p) */
extern unsigned int str_hash(const char* s);
#ifdef __cplusplus
}
#endif
#endif /* _STRSTORE_H_ */
zimpl-3.3.6/src/zimpl/prog.c 0000644 0014172 0006025 00000013744 13304236715 015627 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: prog.c */
/* Name....: Program Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/entry.h"
#include "zimpl/idxset.h"
#include "zimpl/rdefpar.h"
#include "zimpl/bound.h"
#include "zimpl/define.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/list.h"
#include "zimpl/local.h"
#include "zimpl/code.h"
#include "zimpl/stmt.h"
#include "zimpl/prog.h"
#define PROG_SID 0x50726f67
#define PROG_EXTEND_SIZE 100
static void* lp_data = NULL;
struct program
{
SID
int size;
int used;
int extend;
Stmt** stmt;
};
void* prog_get_lp()
{
return lp_data;
}
Prog* prog_new()
{
Prog* prog = calloc(1, sizeof(*prog));
assert(prog != NULL);
prog->size = PROG_EXTEND_SIZE;
prog->used = 0;
prog->extend = PROG_EXTEND_SIZE;
prog->stmt = calloc((size_t)prog->size, sizeof(*prog->stmt));
SID_set(prog, PROG_SID);
assert(prog_is_valid(prog));
return prog;
}
void prog_free(Prog* prog)
{
int i;
assert(prog_is_valid(prog));
assert(prog->stmt != NULL);
SID_del(prog);
for(i = 0; i < prog->used; i++)
stmt_free(prog->stmt[i]);
free(prog->stmt);
free(prog);
}
bool prog_is_valid(const Prog* prog)
{
return ((prog != NULL) && SID_ok(prog, PROG_SID));
}
bool prog_is_empty(const Prog* prog)
{
return prog->used == 0;
}
void prog_add_stmt(Prog* prog, Stmt* stmt)
{
assert(prog_is_valid(prog));
assert(stmt_is_valid(stmt));
assert(prog->used <= prog->size);
if (prog->used == prog->size)
{
prog->size += prog->extend;
prog->extend += prog->extend;
prog->stmt = realloc(
prog->stmt, (size_t)prog->size * sizeof(*prog->stmt));
assert(prog->stmt != NULL);
}
assert(prog->used < prog->size);
prog->stmt[prog->used] = stmt;
prog->used++;
}
void prog_print(FILE* fp, const Prog* prog)
{
int i;
assert(prog_is_valid(prog));
fprintf(fp, "Statements: %d\n", prog->used);
for(i = 0; i < prog->used; i++)
stmt_print(fp, prog->stmt[i]);
}
void prog_execute(const Prog* prog, void* lp)
{
int i;
assert(prog_is_valid(prog));
code_clear_inst_count();
lp_data = lp;
for(i = 0; i < prog->used; i++)
{
stmt_parse(prog->stmt[i]);
stmt_execute(prog->stmt[i]);
/* These calls should make sure, that all output is really
* flushed out, even in a Batch environment.
*/
fflush(stdout);
fflush(stderr);
#ifdef USE_FSYNC
/* This is to force the output do disk. It is to my knowledge
* only needed on AIX batch systems that seem not to flush
* the output buffer. If then the job is killed for some reason
* no output is generated.
*/
(void)fsync(fileno(stdout));
(void)fsync(fileno(stderr));
#endif
}
if (verbose >= VERB_NORMAL)
printf("Instructions evaluated: %u\n", code_get_inst_count());
}
char* prog_tostr(const Prog* prog, const char* prefix, const char* title, size_t max_output_line_len)
{
size_t len;
char* text;
int pos = 0;
int i;
assert(prog_is_valid(prog));
assert(prefix != NULL);
assert(max_output_line_len > strlen(prefix));
/* prefix + title + \n
* prog->used * (\n + prefix + stmt)
* \0
*/
len = strlen(prefix) + strlen(title) + 2;
for(i = 0; i < prog->used; i++)
{
size_t line_len = strlen(stmt_get_text(prog->stmt[i]));
size_t max_eff_line_len = max_output_line_len - strlen(prefix) - 1;
len += line_len + ((line_len + max_eff_line_len - 1) / max_eff_line_len) * (strlen(prefix) + 1);
}
text = calloc(len, sizeof(*text));
pos = sprintf(&text[pos], "%s%s", prefix, title);
for(i = 0; i < prog->used; i++)
{
const char* s = stmt_get_text(prog->stmt[i]);
int k = 0;
while(*s != '\0')
{
if ((size_t)k % max_output_line_len == 0)
{
k = sprintf(&text[pos], "\n%s", prefix);
pos += k;
}
text[pos] = *s;
pos++;
s++;
k++;
}
}
text[pos++] = '\n';
text[pos] = '\0';
/* for(i = 0; i < prog->used; i++)
* pos += sprintf(&text[pos], "%s%s\n", prefix, stmt_get_text(prog->stmt[i]));
*/
assert((size_t)pos + 1 == len);
return text;
}
zimpl-3.3.6/src/zimpl/hash.h 0000644 0014172 0006025 00000007330 13304236715 015602 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: hash.h */
/* Name....: Hash Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _HASH_H_
#define _HASH_H_
#ifndef _NUMB_H_
#error "Need to include numb.h before hash.h"
#endif
#ifndef _ELEM_H_
#error "Need to include elem.h before hash.h"
#endif
#ifndef _TUPLE_H_
#error "Need to include tuple.h before hash.h"
#endif
#ifndef _MME_H_
#error "Need to include mme.h before hash.h (Entry,Mono)"
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum hash_type { HASH_ERR = 0, HASH_TUPLE, HASH_ENTRY, HASH_ELEM_IDX, HASH_NUMB, HASH_MONO };
typedef enum hash_type HashType;
typedef struct hash Hash;
/*lint -sem( hash_new, chneg(2), @P >= malloc(1)) */
extern Hash* hash_new(HashType type, int size);
/*lint -sem( hash_free, custodial(1), cleanup, inout(1), 1P) */
extern void hash_free(Hash* hash);
/*lint -sem( hash_add_tuple, inout(1), 1P >= 1, 2P >= 1) */
extern void hash_add_tuple(Hash* hash, const Tuple* tuple);
/*lint -sem( hash_add_entry, inout(1), 1P >= 1, 2P >= 1) */
extern void hash_add_entry(Hash* hash, const Entry* entry);
/*lint -sem( hash_add_mono, inout(1), 1P >= 1, 2P >= 1) */
extern void hash_add_mono(Hash* hash, const Mono* mono);
/*lint -sem( hash_add_elem_idx, inout(1), 1P >= 1, 2p, chneg(3)) */
extern void hash_add_elem_idx(Hash* hash, const Elem* elem, int idx);
/*lint -sem( hash_add_numb, inout(1), 1P >= 1, 2P >= 1) */
extern void hash_add_numb(Hash* hash, const Numb* numb);
/*lint -sem( hash_has_tuple, pure, 1P >= 1, 2P >= 1) */
extern bool hash_has_tuple(const Hash* hash, const Tuple* tuple);
/*lint -sem( hash_has_entry, pure, 1P >= 1, 2P >= 1) */
extern bool hash_has_entry(const Hash* hash, const Tuple* tuple);
/*lint -sem( hash_has_numb, pure, 1P >= 1, 2P >= 1) */
extern bool hash_has_numb(const Hash* hash, const Numb* numb);
/*lint -sem( hash_lookup_entry, pure, 1P >= 1, 2P >= 1) */
extern const Entry* hash_lookup_entry(const Hash* hash, const Tuple* tuple);
/*lint -sem( hash_lookup_mono, pure, 1P >= 1, 2P >= 1) */
extern const Mono* hash_lookup_mono(const Hash* hash, const Mono* mono);
/*lint -sem( hash_lookup_elem_idx, pure, 1P >= 1, 2P >= 1) */
extern int hash_lookup_elem_idx(const Hash* hash, const Elem* elem);
#ifdef __cplusplus
}
#endif
#endif /* _HASH_H_ */
zimpl-3.3.6/src/zimpl/tuple.c 0000644 0014172 0006025 00000016542 13304236715 016010 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: tuple.c */
/* Name....: Tuple Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/blkmem.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/mme.h"
#include "zimpl/stmt.h"
#include "zimpl/tuple.h"
#define TUPLE_SID 0x5475706c
#define TUPLE_STR_SIZE 100
struct tuple
{
SID
int dim;
int refc;
Elem** element;
};
Tuple* tuple_new(int dim)
{
Tuple* tuple;
int count;
int i;
assert(dim >= 0);
tuple = blk_alloc(sizeof(*tuple));
assert(tuple != NULL);
/* Machen wir hier nur, weil einige Compiler bei malloc(0)
* als Rueckgabe NULL liefern. Das mag das free() nicht.
*/
count = dim < 1 ? 1 : dim;
tuple->dim = dim;
tuple->refc = 1;
tuple->element = calloc((size_t)count, sizeof(*tuple->element));
assert(tuple->element != NULL);
for(i = 0; i < dim; i++)
tuple->element[i] = NULL;
SID_set(tuple, TUPLE_SID);
assert(tuple_is_valid(tuple));
return tuple;
}
void tuple_free(Tuple* tuple)
{
assert(tuple_is_valid(tuple));
assert(tuple->element != NULL);
tuple->refc--;
if (tuple->refc == 0)
{
int i;
for(i = 0; i < tuple->dim; i++)
if (tuple->element[i] != NULL)
elem_free(tuple->element[i]);
SID_del(tuple);
free(tuple->element);
blk_free(tuple, sizeof(*tuple));
}
}
bool tuple_is_valid(const Tuple* tuple)
{
return tuple != NULL && SID_ok(tuple, TUPLE_SID) && tuple->refc > 0;
}
Tuple* tuple_copy(const Tuple* source)
{
Tuple* tuple = (Tuple*)source;
assert(tuple_is_valid(tuple));
tuple->refc++;
return tuple;
}
/* 1 = verschieden,
* 0 = gleich.
*/
bool tuple_cmp(const Tuple* tuple_a, const Tuple* tuple_b)
{
int i;
assert(tuple_is_valid(tuple_a));
assert(tuple_is_valid(tuple_b));
if (tuple_a == tuple_b)
return false;
if (tuple_a->dim != tuple_b->dim)
{
/* Keine Warnung wenn wir mit dem 0-Tuple vergleichen.
*/
if ((tuple_a->dim != 0) && (tuple_b->dim != 0))
{
if (stmt_trigger_warning(167))
{
fprintf(stderr,
"--- Warning 167: Comparison of different dimension tuples ");
tuple_print(stderr, tuple_a);
fprintf(stderr, " ");
tuple_print(stderr, tuple_b);
fputc('\n', stderr);
}
}
return true;
}
assert(tuple_a->dim == tuple_b->dim);
for(i = 0; i < tuple_a->dim; i++)
if (elem_cmp(tuple_a->element[i], tuple_b->element[i]))
break;
return i < tuple_a->dim;
}
int tuple_get_dim(const Tuple* tuple)
{
assert(tuple_is_valid(tuple));
return tuple->dim;
}
/*lint -e{818} supress "Pointer parameter could be declared as pointing to const" */
void tuple_set_elem(Tuple* tuple, int idx, Elem* elem)
{
assert(tuple_is_valid(tuple));
assert(idx >= 0);
assert(idx < tuple->dim);
assert(tuple->refc == 1);
assert(tuple->element[idx] == NULL);
tuple->element[idx] = elem;
}
const Elem* tuple_get_elem(const Tuple* tuple, int idx)
{
assert(tuple_is_valid(tuple));
assert(idx >= 0);
assert(idx < tuple->dim);
/* Abfrage eines noch nicht gesetzten Elements ist illegal.
*/
assert(tuple->element[idx] != NULL);
return tuple->element[idx];
}
Tuple* tuple_combine(const Tuple* ta, const Tuple* tb)
{
Tuple* tuple;
int i;
assert(tuple_is_valid(ta));
assert(tuple_is_valid(tb));
tuple = tuple_new(ta->dim + tb->dim);
for(i = 0; i < ta->dim; i++)
tuple->element[i] = elem_copy(ta->element[i]);
for(i = 0; i < tb->dim; i++)
tuple->element[ta->dim + i] = elem_copy(tb->element[i]);
return tuple;
}
void tuple_print(FILE* fp, const Tuple* tuple)
{
int i;
assert(tuple_is_valid(tuple));
fprintf(fp, "<");
for(i = 0; i < tuple->dim; i++)
{
elem_print(fp, tuple->element[i], true);
fprintf(fp, "%s", (i < tuple->dim - 1) ? "," : "");
}
fprintf(fp, ">");
}
unsigned int tuple_hash(const Tuple* tuple)
{
unsigned int hcode = 0;
int i;
for(i = 0; i < tuple->dim; i++)
hcode = DISPERSE(hcode + elem_hash(tuple->element[i]));
return hcode;
}
#if 0
char* tuple_tostr(const Tuple* tuple)
{
unsigned int size = TUPLE_STR_SIZE;
unsigned int len = 2; /* for the '\0' and the '[' */
char* str = malloc(size);
char* selem;
unsigned int selemlen;
int i;
assert(tuple_is_valid(tuple));
assert(str != NULL);
strcpy(str, "[");
for(i = 0; i < tuple->dim; i++)
{
selem = elem_tostr(tuple->element[i]);
selemlen = strlen(selem) + 1;
if (len + selemlen >= size)
{
size += selemlen + TUPLE_STR_SIZE;
str = realloc(str, size);
assert(str != NULL);
}
assert(len + selemlen < size);
strcat(str, selem);
strcat(str, i < tuple->dim - 1 ? "," : "]");
free(selem);
len += selemlen;
}
return str;
}
#endif
char* tuple_tostr(const Tuple* tuple)
{
size_t size = TUPLE_STR_SIZE;
size_t len = 1; /* one for the zero '\0' */
char* str = malloc(size);
int i;
assert(tuple_is_valid(tuple));
assert(str != NULL);
str[0] = '\0';
for(i = 0; i < tuple->dim; i++)
{
char* selem = elem_tostr(tuple->element[i]);
size_t selemlen = strlen(selem) + 1;
if (len + selemlen >= size)
{
size += selemlen + TUPLE_STR_SIZE;
str = realloc(str, size);
assert(str != NULL);
}
assert(len + selemlen < size);
assert(elem_get_type(tuple->element[i]) == ELEM_NUMB
|| elem_get_type(tuple->element[i]) == ELEM_STRG);
strcat(str, elem_get_type(tuple->element[i]) == ELEM_NUMB ? "#" : "$");
strcat(str, selem);
free(selem);
len += selemlen;
}
return str;
}
zimpl-3.3.6/src/zimpl/setrange.c 0000644 0014172 0006025 00000024070 13304236715 016462 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: setrange.c */
/* Name....: Set Range Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include "zimpl/mshell.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/hash.h"
#include "zimpl/stmt.h"
#include "zimpl/set.h"
#include "zimpl/set4.h"
#ifdef _MSC_VER
#pragma warning (disable: 4100) /* unreferenced formal parameter */
#endif
#define SET_RANGE_SID 0x53455452
#define SET_RANGE_ITER_SID 0x53455249
/* -------------------------------------------------------------------------
* --- valid
* -------------------------------------------------------------------------
*/
static bool set_range_is_valid(const Set* set)
{
return set != NULL
&& SID_ok2(set->range, SET_RANGE_SID)
&& set->head.refc > 0
&& set->head.dim == 1;
}
static bool set_range_iter_is_valid(const SetIter* iter)
{
return iter != NULL && SID_ok2(iter->range, SET_RANGE_ITER_SID)
&& iter->range.first >= 0
&& iter->range.last >= 0
&& iter->range.now >= iter->range.first;
}
/* -------------------------------------------------------------------------
* --- set_new
* -------------------------------------------------------------------------
*/
Set* set_range_new(int begin, int end, int step)
{
Set* set;
set = calloc(1, sizeof(*set));
assert(set != NULL);
set->head.refc = 1;
set->head.dim = 1;
set->head.members = 1 + (end - begin) / step;
set->head.type = SET_RANGE;
set->range.begin = begin;
set->range.end = end;
set->range.step = step;
SID_set2(set->range, SET_RANGE_SID);
assert(set_range_is_valid(set));
return set;
}
/* -------------------------------------------------------------------------
* --- copy
* -------------------------------------------------------------------------
*/
static Set* set_range_copy(const Set* source)
{
Set* set = (Set*)source;
set->head.refc++;
return set;
}
/* -------------------------------------------------------------------------
* --- set_free
* -------------------------------------------------------------------------
*/
static void set_range_free(Set* set)
{
assert(set_range_is_valid(set));
set->head.refc--;
if (set->head.refc == 0)
{
SID_del2(set->range);
free(set);
}
}
/* -------------------------------------------------------------------------
* --- lookup
* -------------------------------------------------------------------------
*/
/* Return index number of element. -1 if not present
*/
static int idx_to_val(SetIterIdx begin, SetIterIdx step, SetIterIdx idx)
{
#if 0
fprintf(stderr, "idx_to_val: %lld %lld %lld = %lld\n",
begin, step, idx, begin + idx * step);
#endif
return begin + idx * step;
}
static SetIterIdx val_to_idx(SetIterIdx begin, SetIterIdx step, SetIterIdx val)
{
#if 0
fprintf(stderr, "val_to_idx: %lld %lld %lld = %lld\n",
begin, step, val, (val - begin) / step);
#endif
return (val - begin) / step;
}
static SetIterIdx set_range_lookup_idx(const Set* set, const Tuple* tuple, int offset)
{
const Elem* elem;
const Numb* numb;
int val;
assert(set_range_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset < tuple_get_dim(tuple));
elem = tuple_get_elem(tuple, offset);
/* If this is true, we asked a number set for a string.
*/
if (elem_get_type(elem) != ELEM_NUMB)
return -1;
numb = elem_get_numb(elem);
assert(numb_is_int(numb));
val = numb_toint(numb);
if (set->range.step > 0)
{
if ( val < set->range.begin
|| val > set->range.end
|| ((val - set->range.begin) % set->range.step) != 0)
return -1;
}
else
{
assert(set->range.step < 0);
if ( val > set->range.begin
|| val < set->range.end
|| ((set->range.begin - val) % set->range.step) != 0)
return -1;
}
return val_to_idx(set->range.begin, set->range.step, val);
}
/* -------------------------------------------------------------------------
* --- get_tuple
* -------------------------------------------------------------------------
*/
static void set_range_get_tuple(
const Set* set,
SetIterIdx idx,
Tuple* tuple,
int offset)
{
int val;
Numb* numb;
assert(set_range_is_valid(set));
assert(idx >= 0);
assert(idx <= set->head.members);
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset < tuple_get_dim(tuple));
val = idx_to_val(set->range.begin, set->range.step, idx);
numb = numb_new_integer(val);
tuple_set_elem(tuple, offset, elem_new_numb(numb));
numb_free(numb);
}
/* -------------------------------------------------------------------------
* --- iter_init
* -------------------------------------------------------------------------
*/
/* Initialise Iterator. Write into iter
*/
static SetIter* set_range_iter_init(
const Set* set,
const Tuple* pattern,
int offset)
{
const Elem* elem;
SetIter* iter;
assert(set_range_is_valid(set));
assert(pattern == NULL || tuple_is_valid(pattern));
assert(offset >= 0);
assert(pattern == NULL || offset < tuple_get_dim(pattern));
iter = calloc(1, sizeof(*iter));
assert(iter != NULL);
if (pattern == NULL)
{
iter->range.first = 0;
iter->range.last = val_to_idx(set->range.begin, set->range.step, set->range.end);
}
else
{
elem = tuple_get_elem(pattern, offset);
switch(elem_get_type(elem))
{
case ELEM_NAME :
iter->range.first = 0;
iter->range.last = val_to_idx(set->range.begin, set->range.step, set->range.end);
break;
case ELEM_NUMB :
iter->range.first = set_range_lookup_idx(set, pattern, offset);
if (iter->range.first >= 0)
iter->range.last = iter->range.first;
else
{
iter->range.first = 1;
iter->range.last = 0;
}
break;
case ELEM_STRG :
/* This should not happen. Probably a set with mixed
* numbers and string was generated.
*/
default :
abort();
}
}
iter->range.now = iter->range.first;
SID_set2(iter->range, SET_RANGE_ITER_SID);
assert(set_range_iter_is_valid(iter));
return iter;
}
/* -------------------------------------------------------------------------
* --- iter_next
* -------------------------------------------------------------------------
*/
/* false means, there is no further element
*/
static bool set_range_iter_next(
SetIter* iter,
const Set* set,
Tuple* tuple,
int offset)
{
int val;
Numb* numb;
assert(set_range_iter_is_valid(iter));
assert(set_range_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset < tuple_get_dim(tuple));
if (iter->range.now > iter->range.last)
return false;
val = idx_to_val(set->range.begin, set->range.step, iter->range.now);
numb = numb_new_integer(val);
tuple_set_elem(tuple, offset, elem_new_numb(numb));
numb_free(numb);
iter->range.now++;
return true;
}
/* -------------------------------------------------------------------------
* --- iter_exit
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_range_iter_exit(SetIter* iter, UNUSED const Set* set)
{
assert(set_range_iter_is_valid(iter));
SID_del2(iter->range);
free(iter);
}
/* -------------------------------------------------------------------------
* --- iter_reset
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_range_iter_reset(SetIter* iter, UNUSED const Set* set)
{
assert(set_range_iter_is_valid(iter));
iter->range.now = iter->range.first;
}
/* -------------------------------------------------------------------------
* --- vtab_init
* -------------------------------------------------------------------------
*/
void set_range_init(SetVTab* vtab)
{
vtab[SET_RANGE].set_copy = set_range_copy;
vtab[SET_RANGE].set_free = set_range_free;
vtab[SET_RANGE].set_lookup_idx = set_range_lookup_idx;
vtab[SET_RANGE].set_get_tuple = set_range_get_tuple;
vtab[SET_RANGE].iter_init = set_range_iter_init;
vtab[SET_RANGE].iter_next = set_range_iter_next;
vtab[SET_RANGE].iter_exit = set_range_iter_exit;
vtab[SET_RANGE].iter_reset = set_range_iter_reset;
vtab[SET_RANGE].set_is_valid = set_range_is_valid;
}
zimpl-3.3.6/src/zimpl/ratlpfwrite.c 0000644 0014172 0006025 00000044360 13304236715 017221 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: lpfwrite.c */
/* Name....: LP Format File Writer */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2003-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include "zimpl/mshell.h"
#include
#include "zimpl/gmpmisc.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/bound.h"
#include "zimpl/mme.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/ratlp.h"
#include "zimpl/ratlpstore.h"
#include "zimpl/random.h"
static void permute(int size, void** tab)
{
int i;
if (size < 3)
return;
assert(size >= 3);
for(i = 0; i < size; i++)
{
void* t;
int a = rand_get_range(0, size - 1); /*lint !e426 Call to function violates semantic (1n<2n)*/
int b = rand_get_range(0, size - 1); /*lint !e426 Call to function violates semantic (1n<2n)*/
assert(a >= 0);
assert(a < size);
assert(b >= 0);
assert(b < size);
t = tab[a];
tab[a] = tab[b];
tab[b] = t;
}
}
static void write_val(FILE* fp, LpFormat format, bool force_sign, const mpq_t val)
{
switch(format)
{
case LP_FORM_LPF :
case LP_FORM_RLP :
case LP_FORM_PIP :
fprintf(fp, force_sign ? "%+.15g" : "%.15g", mpq_get_d(val));
break;
case LP_FORM_HUM :
if (force_sign && (mpq_sgn(val) > 0)) /*lint !e634 !e638 Strong type mismatch (type 'Bool') */
fprintf(fp, "+");
(void)mpq_out_str(fp, 10, val);
break;
default:
abort();
}
}
static void write_lhs(FILE* fp, LpFormat format, const Con* con, ConType type)
{
assert(fp != NULL);
assert(con != NULL);
switch(type)
{
case CON_RHS :
case CON_LHS :
case CON_EQUAL :
break;
case CON_RANGE :
write_val(fp, format, false, con->lhs);
fprintf(fp, " <= ");
break;
default :
abort();
}
}
static void write_rhs(FILE* fp, LpFormat format, const Con* con, ConType type)
{
assert(fp != NULL);
assert(con != NULL);
switch(type)
{
case CON_RHS :
case CON_RANGE :
fprintf(fp, " <= ");
write_val(fp, format, false, con->rhs);
break;
case CON_LHS :
fprintf(fp, " >= ");
write_val(fp, format, false, con->lhs);
break;
case CON_EQUAL :
fprintf(fp, " = ");
write_val(fp, format, false, con->rhs);
break;
default :
abort();
}
fprintf(fp, "\n");
}
static void write_row(
FILE* fp,
LpFormat format,
const Con* con,
char* name,
int name_size)
{
Nzo* nzo;
Nzo** nzotab;
int cnt;
int i;
assert(fp != NULL);
assert(con != NULL);
assert(name != NULL);
/* Add 1 in case con->size == 0
*/
nzotab = calloc((size_t)con->size + 1, sizeof(*con));
assert(nzotab != NULL);
for(cnt = 0, nzo = con->first; nzo != NULL; nzo = nzo->con_next)
nzotab[cnt++] = nzo;
assert(cnt == con->size);
if (format == LP_FORM_RLP)
permute(con->size, (void**)nzotab);
cnt = 0;
for(i = 0; i < con->size; i++)
{
nzo = nzotab[i];
lps_makename(name, name_size, nzo->var->name, format == LP_FORM_HUM ? -1 : nzo->var->number);
if (mpq_equal(nzo->value, const_one))
fprintf(fp, " + %s", name);
else if (mpq_equal(nzo->value, const_minus_one))
fprintf(fp, " - %s", name);
else
{
fprintf(fp, " ");
write_val(fp, format, true, nzo->value);
fprintf(fp, " %s", name);
}
if (++cnt % 6 == 0)
fprintf(fp, "\n ");
}
if (con->qme_first != NULL)
{
Qme* qme;
if (cnt % 6 != 0)
fprintf(fp, "\n ");
cnt = 0;
if (format == LP_FORM_LPF || format == LP_FORM_RLP)
fprintf(fp, " + [");
for(qme = con->qme_first; qme != NULL; qme= qme->next)
{
lps_makename(name, name_size, qme->var1->name, format == LP_FORM_HUM ? -1 : qme->var1->number);
if (mpq_equal(qme->value, const_one))
fprintf(fp, " + %s", name);
else if (mpq_equal(qme->value, const_minus_one))
fprintf(fp, " - %s", name);
else
{
fprintf(fp, " ");
write_val(fp, format, true, qme->value);
fprintf(fp, " %s", name);
}
if (qme->var1 == qme->var2)
fprintf(fp, "^2");
else
{
lps_makename(name, name_size, qme->var2->name, format == LP_FORM_HUM ? -1 : qme->var2->number);
fprintf(fp, " * %s", name);
}
if (++cnt % 6 == 0)
fprintf(fp, "\n ");
}
if (format == LP_FORM_LPF || format == LP_FORM_RLP)
{
fprintf(fp, " ]\n");
cnt = 0;
}
}
if (con->term != NULL)
{
const Term* term = con->term;
bool only_comment = false;
assert(term_get_degree(term) > 2 || !term_is_polynomial(term));
if (format != LP_FORM_PIP)
{
if (verbose > 0)
{
fprintf(stderr, "--- Warning 600: File format can only handle linear and quadratic constraints\n");
fprintf(stderr, " Constraint %s with degree %d ignored\n",
con->name, term_get_degree(term));
}
only_comment = true;
}
assert(numb_equal(term_get_constant(term), numb_zero()));
if (cnt % 6 != 0)
fprintf(fp, "\n ");
cnt = 0;
if (only_comment)
fprintf(fp, "\\ ");
for(i = 0; i < term_get_elements(term); i++)
{
const Mono* mono = term_get_element(term, i);
const Numb* coeff = mono_get_coeff(mono);
MFun fun = mono_get_function(mono);
int k;
if (fun == MFUN_NONE)
{
if (numb_equal(coeff, numb_one()))
fprintf(fp, " +");
else
{
mpq_t t;
mpq_init(t);
numb_get_mpq(coeff, t);
fprintf(fp, " ");
write_val(fp, format, true, t);
mpq_clear(t);
}
fputc(' ', fp);
}
else
{
switch(fun)
{
case MFUN_SQRT :
fprintf(fp, " + sqrt(");
break;
case MFUN_LOG :
fprintf(fp, " + log(");
break;
case MFUN_EXP :
fprintf(fp, " + exp(");
break;
case MFUN_LN :
fprintf(fp, " + ln(");
break;
case MFUN_SIN :
fprintf(fp, " + sin(");
break;
case MFUN_COS :
fprintf(fp, " + cos(");
break;
case MFUN_TAN :
fprintf(fp, " + tan(");
break;
case MFUN_ABS :
fprintf(fp, " + abs(");
break;
case MFUN_SGN :
fprintf(fp, " + sgn(");
break;
case MFUN_POW :
fprintf(fp, " + pow(");
break;
case MFUN_SGNPOW :
fprintf(fp, " + sgnpow(");
break;
case MFUN_TRUE :
case MFUN_FALSE :
break;
default :
abort();
}
}
for(k = 0; k < mono_get_degree(mono); k++)
{
Var* var = mono_get_var(mono, k);
int j;
if (k > 0)
fprintf(fp, " * ");
for(j = 1; k + j < mono_get_degree(mono); j++)
if (var != mono_get_var(mono, k + j))
break;
lps_makename(name, name_size, var->name, format == LP_FORM_HUM ? -1 : var->number);
if (j == 1)
fprintf(fp, "%s", name);
else
{
fprintf(fp, "%s^%d", name, j);
k += j - 1; /*lint !e850 loop index variable is modified in body of the loop */
}
}
if (fun != MFUN_NONE)
{
if (fun == MFUN_POW || fun == MFUN_SGNPOW)
{
mpq_t t;
mpq_init(t);
numb_get_mpq(coeff, t);
fprintf(fp, " ,");
write_val(fp, format, false, t);
mpq_clear(t);
}
fprintf(fp, ") ");
}
if (++cnt % 6 == 0)
fprintf(fp, "\n%s ", only_comment ? "\\" : "");
}
}
free(nzotab);
}
/* A specification for the LP file format can be found in the
* ILOG CPLEX 7.0 Reference Manual page 527.
* ILOG CPLEX 8.0 Reference Manual page 595.
* The "Lazy Constraints" section seems to be undocumented.
*/
void lpf_write(
const Lps* lp,
FILE* fp,
LpFormat format,
const char* text)
{
const Var* var;
Con* con;
Con** contab;
bool have_integer = false;
bool have_separate = false;
bool have_checkonly = false;
int cnt;
int i;
int k;
int name_size;
char* name;
assert(lp != NULL);
assert(fp != NULL);
/* Store constraint pointers and permute them
* (add 1 in case lp->cons == 0)
*/
contab = calloc((size_t)lp->cons + 1, sizeof(*contab));
assert(contab != NULL);
k = 0;
for(con = lp->con_root; con != NULL; con = con->next)
contab[k++] = con;
assert(k == lp->cons);
if (format == LP_FORM_RLP)
permute(lp->cons, (void**)contab);
name_size = lps_getnamesize(lp, LP_FORM_LPF);
name = malloc((size_t)name_size);
assert(name != NULL);
if (text != NULL)
fprintf(fp, "%s", text);
fprintf(fp, "\\Problem name: %s\n", lp->name);
fprintf(fp, "%s\n", (lp->direct == LP_MIN) ? "Minimize" : "Maximize");
fprintf(fp, " %s: ", lp->objname == NULL ? "Objective" : lp->objname);
for(var = lp->var_root, cnt = 0; var != NULL; var = var->next)
{
/* If cost is zero, do not include in objective function
*/
if (mpq_equal(var->cost, const_zero))
continue;
lps_makename(name, name_size, var->name, format == LP_FORM_HUM ? -1 : var->number);
if (mpq_equal(var->cost, const_one))
fprintf(fp, " + %s", name);
else if (mpq_equal(var->cost, const_minus_one))
fprintf(fp, " - %s", name);
else
{
fprintf(fp, " ");
write_val(fp, format, true, var->cost);
fprintf(fp, " %s", name);
}
if (++cnt % 6 == 0)
fprintf(fp, "\n ");
}
/* ---------------------------------------------------------------------- */
/* First loop run for normal constraints, second one for
* user cuts, thrid one for lazy constraints, if any.
*/
for(i = 0; i < 3; i++)
{
if (i == 0)
fprintf(fp, "\nSubject to\n");
else if (i == 1)
{
if (!have_separate)
continue;
else
fprintf(fp, "\nUser Cuts\n");
}
else if (i == 2)
{
if (!have_checkonly)
continue;
else
fprintf(fp, "\nLazy Constraints\n");
}
for(k = 0; k < lp->cons; k++)
{
con = contab[k];
if (con->size == 0 && con->qme_first == NULL && con->term == NULL)
continue;
if (i == 0 && ((con->flags & (LP_FLAG_CON_SEPAR | LP_FLAG_CON_CHECK)) != 0))
{
if ((con->flags & LP_FLAG_CON_SEPAR) == LP_FLAG_CON_SEPAR)
have_separate = true;
if ((con->flags & LP_FLAG_CON_CHECK) == LP_FLAG_CON_CHECK)
have_checkonly = true;
continue;
}
if (i == 1 && (con->flags & LP_FLAG_CON_SEPAR) != LP_FLAG_CON_SEPAR)
continue;
if (i == 2 && (con->flags & LP_FLAG_CON_CHECK) != LP_FLAG_CON_CHECK)
continue;
if (con->type == CON_RANGE)
{
if (format == LP_FORM_HUM)
{
lps_makename(name, name_size, con->name, -1);
fprintf(fp, " %s:\n ", name);
write_lhs(fp, format, con, CON_RANGE);
write_row(fp, format, con, name, name_size);
write_rhs(fp, format, con, CON_RANGE);
}
else
{
/* Split ranges, because LP format can't handle them.
*/
lps_makename(name, name_size, con->name, con->number);
fprintf(fp, " %sR:\n ", name);
write_row(fp, format, con, name, name_size); /* changes name */
write_rhs(fp, format, con, CON_RHS);
lps_makename(name, name_size, con->name, con->number);
fprintf(fp, " %sL:\n ", name);
write_row(fp, format, con, name, name_size); /* changes name */
write_rhs(fp, format, con, CON_LHS);
}
}
else
{
lps_makename(name, name_size, con->name, format == LP_FORM_HUM ? -1 : con->number);
if (i == 0)
fprintf(fp, " %s:\n ", name);
else if (i == 1)
fprintf(fp, " %sU:\n ", name);
else if (i == 2)
fprintf(fp, " %sZ:\n ", name);
if (con->ind_var != NULL)
{
lps_makename(name, name_size, con->ind_var->name, format == LP_FORM_HUM ? -1 : con->ind_var->number);
fprintf(fp, "%s = %d -> ", name, con->ind_dir ? 1 : 0);
}
write_row(fp, format, con, name, name_size);
write_rhs(fp, format, con, con->type);
}
}
}
/* ---------------------------------------------------------------------- */
fprintf(fp, "Bounds\n");
for(var = lp->var_root; var != NULL; var = var->next)
{
/* A variable without any entries in the matrix
* or the objective function can be ignored.
* (also not part of an SOS or quadratic constraint)
*/
if (var->size == 0 && mpq_equal(var->cost, const_zero) && !var->is_used)
continue;
lps_makename(name, name_size, var->name, format == LP_FORM_HUM ? -1 : var->number);
if (var->type == VAR_FIXED)
{
fprintf(fp, " %s = ", name);
write_val(fp, format, false, var->lower);
fprintf(fp, "\n");
}
else
{
/* Check if we have integer variables
*/
if (var->vclass == VAR_INT)
have_integer = true;
fprintf(fp, " ");
if (var->type == VAR_LOWER || var->type == VAR_BOXED)
write_val(fp, format, false, var->lower);
else
fprintf(fp, "-inf");
fprintf(fp, " <= %s <= ", name);
if (var->type == VAR_UPPER || var->type == VAR_BOXED)
{
write_val(fp, format, false, var->upper);
fprintf(fp, "\n");
}
else
fprintf(fp, "+inf\n");
}
}
/* ---------------------------------------------------------------------- */
if (have_integer)
{
fprintf(fp, "General\n");
for(var = lp->var_root; var != NULL; var = var->next)
{
if (var->vclass != VAR_INT)
continue;
if (var->size == 0 && mpq_equal(var->cost, const_zero) && !var->is_used)
continue;
lps_makename(name, name_size, var->name, format == LP_FORM_HUM ? -1 : var->number);
fprintf(fp, " %s\n", name);
}
}
/* ---------------------------------------------------------------------- */
if (lps_has_sos(lp))
{
const Sos* sos;
const Sse* sse;
fprintf(fp, "SOS\n");
for(sos = lp->sos_root; sos != NULL; sos = sos->next)
{
cnt = 0;
fprintf(fp, " %s:S%d:: ",
sos->name,
sos->type == SOS_TYPE1 ? 1 : 2);
for(sse = sos->first; sse != NULL; sse = sse->next)
{
lps_makename(name, name_size, sse->var->name, format == LP_FORM_HUM ? -1 : sse->var->number);
fprintf(fp, " %s:", name);
write_val(fp, format, false, sse->weight);
if (++cnt % 6 == 0)
fputc('\n', fp);
}
if (cnt % 6 != 0)
fputc('\n', fp);
}
}
fprintf(fp, "End\n");
free(name);
free(contab);
}
/* ------------------------------------------------------------------------- */
/* Emacs Local Variables: */
/* Emacs mode:c */
/* Emacs c-basic-offset:3 */
/* Emacs tab-width:8 */
/* Emacs indent-tabs-mode:nil */
/* Emacs End: */
/* ------------------------------------------------------------------------- */
zimpl-3.3.6/src/zimpl/setmulti.c 0000644 0014172 0006025 00000045725 13304236715 016532 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: setmulti.c */
/* Name....: Set Multi Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/list.h"
#include "zimpl/hash.h"
#include "zimpl/stmt.h"
#include "zimpl/set.h"
#include "zimpl/entry.h"
#include "zimpl/set4.h"
#ifdef _MSC_VER
#pragma warning (disable: 4100) /* unreferenced formal parameter */
#endif
#define SET_MULTI_SID 0x5345544d
#define SET_MULTI_ITER_SID 0x53454d49
/* This is a bloody hack. But there seems to be no easy way to give
* additional information to the compare routine needed for qsort().
*/
static const Set* cmp_set = NULL;
static int cmp_dim = 0;
/* -------------------------------------------------------------------------
* --- valid
* -------------------------------------------------------------------------
*/
static bool set_multi_is_valid(const Set* set)
{
return set != NULL
&& SID_ok2(set->multi, SET_MULTI_SID)
&& set->head.refc > 0
&& set->head.dim > 1
&& set->multi.subset != NULL
&& set->multi.set != NULL;
}
static bool set_multi_iter_is_valid(const SetIter* iter)
{
return iter != NULL
&& SID_ok2(iter->multi, SET_MULTI_ITER_SID)
&& iter->multi.members >= 0
&& iter->multi.now >= 0
&& ( (iter->multi.members == 0 && iter->multi.dim == 0 && iter->multi.subset == NULL)
|| (iter->multi.members >= 0 && iter->multi.dim > 0 && iter->multi.subset != NULL));
}
/* -------------------------------------------------------------------------
* --- internal
* -------------------------------------------------------------------------
*/
static int subset_cmp(const void* a, const void* b)
{
const SetIterIdx* aa = (const SetIterIdx*)a;
const SetIterIdx* bb = (const SetIterIdx*)b;
for(int i = 0; i < cmp_dim; i++)
{
SetIterIdx d = aa[i] - bb[i];
if (d < 0)
return -1;
if (d > 0)
return 1;
}
return 0;
}
static int order_cmp(const void* a, const void* b)
{
const SetIterIdx* aa = (const SetIterIdx*)a;
const SetIterIdx* bb = (const SetIterIdx*)b;
assert(cmp_set != NULL);
assert(cmp_dim >= 0);
assert(cmp_dim < cmp_set->head.dim);
SetIterIdx ai = *aa * cmp_set->head.dim + cmp_dim;
SetIterIdx bi = *bb * cmp_set->head.dim + cmp_dim;
SetIterIdx d = cmp_set->multi.subset[ai] - cmp_set->multi.subset[bi];
if (d < 0)
return -1;
if (d > 0)
return 1;
return 0;
}
/* -------------------------------------------------------------------------
* --- new
* -------------------------------------------------------------------------
*/
Set* set_multi_new_from_list(const List* list, SetCheckType check)
{
assert(list_is_valid(list));
ListElem* le = NULL;
Hash* hash = NULL;
bool is_entrylist = list_is_entrylist(list);
int n = list_get_elems(list);
const Tuple* tuple = is_entrylist
? entry_get_tuple(list_get_entry(list, &le))
: list_get_tuple(list, &le);
int dim = tuple_get_dim(tuple);
assert(n > 0);
assert(dim > 1);
Set* set = calloc(1, sizeof(*set));
assert(set != NULL);
set->head.refc = 1;
set->head.dim = dim;
set->head.members = 0;
set->head.type = SET_MULTI;
set->multi.set = calloc((size_t)dim, sizeof(*set->multi.set));
set->multi.subset = calloc((size_t)(n * dim), sizeof(*set->multi.subset));
set->multi.order = calloc((size_t)dim, sizeof(*set->multi.order));
assert(set->multi.set != NULL);
assert(set->multi.subset != NULL);
assert(set->multi.order != NULL);
for(int k = 0; k < dim; k++)
set->multi.set[k] = set_list_new(n, SET_DEFAULT);
if (check != SET_CHECK_NONE)
hash = hash_new(HASH_TUPLE, n);
le = NULL;
for(int i = 0; i < n; i++)
{
tuple = is_entrylist
? entry_get_tuple(list_get_entry(list, &le))
: list_get_tuple(list, &le);
assert(tuple != NULL);
assert(hash != NULL || check == SET_CHECK_NONE);
if (hash != NULL && hash_has_tuple(hash, tuple))
{
if (check == SET_CHECK_WARN)
{
if (stmt_trigger_warning(164))
{
fprintf(stderr, "--- Warning 164: Duplicate element ");
tuple_print(stderr, tuple);
fprintf(stderr, " for set rejected\n");
}
}
}
else
{
if (hash != NULL)
hash_add_tuple(hash, tuple);
for(int k = 0; k < dim; k++)
set->multi.subset[set->head.members * dim + k] =
set_list_add_elem(set->multi.set[k],
tuple_get_elem(tuple, k), SET_CHECK_QUIET);
set->head.members++;
}
}
if (hash != NULL)
hash_free(hash);
/* Bloody hack!
*/
cmp_set = set;
cmp_dim = dim;
/* Sort subset
*/
qsort(set->multi.subset, (size_t)set->head.members,
(size_t)dim * sizeof(*set->multi.subset), subset_cmp);
/* This could be done also later On-Demand
*/
for(int k = 0; k < dim; k++)
{
set->multi.order[k] = calloc((size_t)set->head.members, sizeof(**set->multi.order));
assert(set->multi.order[k] != NULL);
for(SetIterIdx i = 0; i < set->head.members; i++)
set->multi.order[k][i] = i;
/* No need to sort order[0] because subset ist already sorted.
*/
if (k > 0)
{
cmp_dim = k;
qsort(set->multi.order[k], (size_t)set->head.members,
sizeof(**set->multi.order), order_cmp);
}
#ifndef NDEBUG
/* Make sure order is sorted
*/
for(SetIterIdx i = 0; i < set->head.members - 1; i++)
{
SetIterIdx a = set->multi.order[k][i] * set->head.dim + k;
SetIterIdx b = set->multi.order[k][i + 1] * set->head.dim + k;
assert(set->multi.subset[a] <= set->multi.subset[b]);
}
#endif /* !NDEBUG */
}
SID_set2(set->multi, SET_MULTI_SID);
assert(set_multi_is_valid(set));
#ifndef NDEBUG
le = NULL;
for(int i = 0; i < n; i++)
{
tuple = is_entrylist
? entry_get_tuple(list_get_entry(list, &le))
: list_get_tuple(list, &le);
assert(set_lookup(set, tuple));
}
#endif
return set;
}
/* -------------------------------------------------------------------------
* --- copy
* -------------------------------------------------------------------------
*/
static Set* set_multi_copy(const Set* source)
{
Set* set = (Set*)source;
int i;
assert(set_multi_is_valid(source));
set->head.refc++;
for(i = 0; i < set->head.dim; i++)
(void)set_copy(set->multi.set[i]);
return set;
}
/* -------------------------------------------------------------------------
* --- free
* -------------------------------------------------------------------------
*/
static void set_multi_free(Set* set)
{
int i;
assert(set_multi_is_valid(set));
for(i = 0; i < set->head.dim; i++)
set_free(set->multi.set[i]);
set->head.refc--;
if (set->head.refc == 0)
{
SID_del2(set->multi);
for(i = 0; i < set->head.dim; i++)
free(set->multi.order[i]);
free(set->multi.order);
free(set->multi.set);
free(set->multi.subset);
free(set);
}
}
/* -------------------------------------------------------------------------
* --- lookup
* -------------------------------------------------------------------------
*/
static int subset_idx_cmp(const void* a, const void* b)
{
const SetIterIdx* key = (const SetIterIdx*)a;
const SetIterIdx* subset = (const SetIterIdx*)b;
int i;
assert(key != NULL);
assert(subset != NULL);
assert(cmp_dim > 0);
for(i = 0; i < cmp_dim; i++)
{
SetIterIdx d = key[i] - subset[i];
if (d < 0)
return -1;
if (d > 0)
return 1;
}
return 0;
}
static int order_idx_cmp(const void* a, const void* b)
{
const SetIterIdx* key = (const SetIterIdx*)a;
const SetIterIdx* order = (const SetIterIdx*)b;
assert(key != NULL);
assert(order != NULL);
assert(cmp_set != NULL);
assert(cmp_dim >= 0);
assert(cmp_dim < cmp_set->head.dim);
assert(*order >= 0);
assert(*order < cmp_set->head.members);
SetIterIdx d = *key - cmp_set->multi.subset[*order * cmp_set->head.dim + cmp_dim];
if (d < 0)
return -1;
if (d > 0)
return 1;
return 0;
}
/* return the index of the element, -1 if not found
*/
static SetIterIdx set_multi_lookup_idx(const Set* set, const Tuple* tuple, int offset)
{
SetIterIdx* idx;
ptrdiff_t result;
assert(set_multi_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset < tuple_get_dim(tuple));
idx = malloc((size_t)set->head.dim * sizeof(*idx));
assert(idx != NULL);
for(int i = 0; i < set->head.dim; i++)
{
idx[i] = set_lookup_idx(set->multi.set[i], tuple, offset + i);
if (idx[i] < 0)
{
free(idx);
return -1;
}
}
cmp_dim = set->head.dim;
result = (ptrdiff_t)bsearch(idx, set->multi.subset, (size_t)set->head.members,
(size_t)set->head.dim * sizeof(*set->multi.subset), subset_idx_cmp);
free(idx);
if (result == 0)
return -1;
assert((result - (ptrdiff_t)set->multi.subset)
% (ptrdiff_t)((size_t)set->head.dim * sizeof(*set->multi.subset)) == 0);
SetIterIdx k = (SetIterIdx)(result - (ptrdiff_t)set->multi.subset)
/ (ptrdiff_t)((size_t)set->head.dim * sizeof(*set->multi.subset));
assert(k >= 0);
assert(k < set->head.members);
return k;
}
/* -------------------------------------------------------------------------
* --- get_tuple
* -------------------------------------------------------------------------
*/
static void set_multi_get_tuple(
const Set* set,
SetIterIdx idx,
Tuple* tuple,
int offset)
{
assert(set_multi_is_valid(set));
assert(idx >= 0);
assert(idx <= set->head.members);
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset + set->head.dim <= tuple_get_dim(tuple));
for(int i = 0; i < set->head.dim; i++)
{
tuple_set_elem(tuple, offset + i,
elem_copy(set_list_get_elem(set->multi.set[i],
set->multi.subset[idx * set->head.dim + i])));
}
}
/* -------------------------------------------------------------------------
* --- iter_init
* -------------------------------------------------------------------------
*/
static SetIter* set_multi_iter_init(
const Set* set,
const Tuple* pattern,
int offset)
{
SetIter* iter;
SetIterIdx* idx;
int i;
SetIterIdx j;
int k;
int m;
int first;
int last;
ptrdiff_t result;
int fixed_idx = -1;
assert(set_multi_is_valid(set));
assert(pattern == NULL || tuple_is_valid(pattern));
assert(offset >= 0);
assert(pattern == NULL || offset < tuple_get_dim(pattern));
iter = calloc(1, sizeof(*iter));
assert(iter != NULL);
idx = malloc((size_t)set->head.dim * sizeof(*idx));
assert(idx != NULL);
for(i = 0; i < set->head.dim; i++)
{
if (pattern == NULL
|| elem_get_type(tuple_get_elem(pattern, offset + i)) == ELEM_NAME)
idx[i] = -1;
else
{
idx[i] = set_lookup_idx(set->multi.set[i], pattern, offset + i);
if (idx[i] < 0)
break;
fixed_idx = i;
}
}
/* Impossible pattern ?
*/
if (i < set->head.dim)
{
iter->multi.members = 0;
iter->multi.now = 0;
}
else
{
iter->multi.dim = set->head.dim;
iter->multi.subset = calloc((size_t)set->head.members,
(size_t)set->head.dim * sizeof(*iter->multi.subset));
assert(iter->multi.subset);
/* Pattern matches all members ?
*/
if (fixed_idx < 0)
{
iter->multi.members = set->head.members;
iter->multi.now = 0;
memcpy(iter->multi.subset, set->multi.subset,
(size_t)(iter->multi.members * iter->multi.dim) * sizeof(*iter->multi.subset));
}
else
{
assert(fixed_idx >= 0);
cmp_set = set;
cmp_dim = fixed_idx;
result = (ptrdiff_t)bsearch(
&idx[fixed_idx],
set->multi.order[fixed_idx],
(size_t)set->head.members,
sizeof(**set->multi.order),
order_idx_cmp);
#if 0
if (result == 0)
{
for(i = 0; i < set->head.members; i++)
fprintf(stderr, "%d %d %d\n", i, set->multi.order[fixed_idx][i],
set->multi.subset[set->multi.order[fixed_idx][i] * set->head.dim + fixed_idx]);
}
#endif
assert(result != 0);
k = (int)(result - (ptrdiff_t)set->multi.order[fixed_idx])
/ (ptrdiff_t)sizeof(**set->multi.order);
assert(k >= 0);
assert(k < set->head.members);
j = set->multi.order[fixed_idx][k];
assert(j >= 0);
assert(j < set->head.members);
assert(idx[fixed_idx] == set->multi.subset[j * set->head.dim + fixed_idx]);
#if 0
fprintf(stderr, "@ fixe_idx: %d idx[]=%d k=%d j=%d\n",
fixed_idx, idx[fixed_idx], k, j);
#endif
for(first = k; first >= 0; first--)
{
j = set->multi.order[fixed_idx][first] * set->head.dim + fixed_idx;
if (idx[fixed_idx] != set->multi.subset[j])
{
assert(idx[fixed_idx] > set->multi.subset[j]);
break;
}
}
for(last = k; last < set->head.members; last++)
{
j = set->multi.order[fixed_idx][last] * set->head.dim + fixed_idx;
if (idx[fixed_idx] != set->multi.subset[j])
{
assert(idx[fixed_idx] < set->multi.subset[j]);
break;
}
}
assert(first + 1 < last);
m = 0;
for(k = first + 1; k < last; k++)
{
j = set->multi.order[fixed_idx][k];
assert(idx[fixed_idx] == set->multi.subset[j * set->head.dim + fixed_idx]);
for(i = 0; i < set->head.dim; i++)
{
/* can entry match ?
*/
if (idx[i] >= 0 && idx[i] != set->multi.subset[j * set->head.dim + i])
break;
iter->multi.subset[m * set->head.dim + i] =
set->multi.subset[j * set->head.dim + i];
}
if (i == set->head.dim)
m++;
}
iter->multi.members = m;
iter->multi.now = 0;
}
}
#if 0
fprintf(stderr, "set_multi_iter_init dim=%d members=%d\n",
set->head.dim, iter->multi.members);
for(i = 0; i < set->head.dim; i++)
fprintf(stderr, "idx[%d]=%d\n", i, idx[i]);
#endif
free(idx);
SID_set2(iter->multi, SET_MULTI_ITER_SID);
assert(set_multi_iter_is_valid(iter));
return iter;
}
/* -------------------------------------------------------------------------
* --- iter_next
* -------------------------------------------------------------------------
*/
/* false means, there is no further element
*/
static bool set_multi_iter_next(
SetIter* iter,
const Set* set,
Tuple* tuple,
int offset)
{
assert(set_multi_iter_is_valid(iter));
assert(set_multi_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset + set->head.dim <= tuple_get_dim(tuple));
if (iter->multi.now >= iter->multi.members)
return false;
for(int i = 0; i < iter->multi.dim; i++)
tuple_set_elem(tuple, offset + i,
elem_copy(set_list_get_elem(set->multi.set[i],
iter->multi.subset[iter->multi.now * iter->multi.dim + i])));
iter->multi.now++;
return true;
}
/* -------------------------------------------------------------------------
* --- iter_exit
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_multi_iter_exit(SetIter* iter, UNUSED const Set* set)
{
assert(set_multi_iter_is_valid(iter));
SID_del2(iter->multi);
if (iter->multi.subset != NULL)
free(iter->multi.subset);
free(iter);
}
/* -------------------------------------------------------------------------
* --- iter_reset
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_multi_iter_reset(SetIter* iter, UNUSED const Set* set)
{
assert(set_multi_iter_is_valid(iter));
iter->multi.now = 0;
}
/* -------------------------------------------------------------------------
* --- vtab_init
* -------------------------------------------------------------------------
*/
void set_multi_init(SetVTab* vtab)
{
vtab[SET_MULTI].set_copy = set_multi_copy;
vtab[SET_MULTI].set_free = set_multi_free;
vtab[SET_MULTI].set_lookup_idx = set_multi_lookup_idx;
vtab[SET_MULTI].set_get_tuple = set_multi_get_tuple;
vtab[SET_MULTI].iter_init = set_multi_iter_init;
vtab[SET_MULTI].iter_next = set_multi_iter_next;
vtab[SET_MULTI].iter_exit = set_multi_iter_exit;
vtab[SET_MULTI].iter_reset = set_multi_iter_reset;
vtab[SET_MULTI].set_is_valid = set_multi_is_valid;
}
zimpl-3.3.6/src/zimpl/strstore2.c 0000644 0014172 0006025 00000007732 13304236715 016627 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: strstore2.c */
/* Name....: String Storage Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include "zimpl/lint.h"
#include "zimpl/mshell.h"
#include "zimpl/strstore.h"
#include "zimpl/mme.h"
typedef struct string_storage StrStore;
struct string_storage
{
char* begin;
size_t size;
size_t used;
StrStore* next;
};
#define MIN_STR_STORE_SIZE 65536UL /* 64k */
#define MAX_STR_STORE_SIZE 1073741824UL /* 1G */
static StrStore* store_anchor = NULL;
static size_t store_size = MIN_STR_STORE_SIZE;
static void extend_storage(void)
{
StrStore* store;
assert(store_size > 0);
/* Since we will not allocate anything again in this block, resize it to fit.
* (not clear if this is really usefull)
*/
if (store_anchor != NULL)
{
store_anchor->begin =
realloc(store_anchor->begin, store_anchor->used * sizeof(*store_anchor->begin));
store_anchor->size = store_anchor->used;
}
store = calloc(1, sizeof(*store_anchor));
assert(store != NULL);
store->size = store_size;
store->used = 0;
store->next = store_anchor;
store->begin = calloc(store_size, sizeof(*store->begin));
assert(store->begin != NULL);
store_anchor = store;
}
const char* str_new(const char* s)
{
char* t;
size_t len;
assert(store_anchor != NULL);
assert(s != NULL);
len = strlen(s) + 1;
if (len > MAX_STR_STORE_SIZE)
{
fprintf(stderr, "*** Error 803: String too long %zu > %zu\n",
len + 1, (size_t)MAX_STR_STORE_SIZE);
zpl_exit(EXIT_FAILURE);
}
if (store_anchor->size - store_anchor->used < len)
{
/* Double the store_size at least once each time,
* but more often in case it is not big enough to hold a very long
* string.
*/
if (store_size < MAX_STR_STORE_SIZE)
{
do
{
store_size *= 2;
}
while(len > store_size);
}
extend_storage();
}
assert(store_anchor->size - store_anchor->used >= len);
t = &store_anchor->begin[store_anchor->used];
store_anchor->used += len;
return strcpy(t, s);
}
void str_init(void)
{
extend_storage();
}
void str_exit(void)
{
StrStore* p;
StrStore* q;
for(p = store_anchor; p != NULL; p = q)
{
q = p->next;
free(p->begin);
free(p);
}
store_anchor = NULL;
}
unsigned int str_hash(const char* s)
{
#if 0
return (unsigned int)s;
#else
unsigned int sum = 0;
int i;
for(i = 0; s[i] != '\0'; i++)
sum = sum * 31 + (unsigned int)s[i];
return sum;
#endif
}
zimpl-3.3.6/src/zimpl/list.h 0000644 0014172 0006025 00000010526 13304236715 015633 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: list.h */
/* Name....: List Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _LIST_H_
#define _LIST_H_
#ifndef _MME_H_
#error "Need to include mme.h before list.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define LIST_NULL ((List*)0)
/*lint -sem( list_new_elem, 1p == 1, @P > malloc(1P)) */
extern List* list_new_elem(const Elem* elem);
/*lint -sem( list_new_tuple, 1p == 1, @P > malloc(1P)) */
extern List* list_new_tuple(const Tuple* tuple);
/*lint -sem( list_new_entry, 1p == 1, @P > malloc(1P)) */
extern List* list_new_entry(const Entry* entry);
/*lint -sem( list_new_list, 1p == 1, @P > malloc(1P)) */
extern List* list_new_list(const List* list);
/*lint -sem( list_free, custodial(1), 1p == 1) */
extern void list_free(List* list);
/*lint -sem( list_is_valid, 1p == 1) */
extern bool list_is_valid(const List* list);
/*lint -sem( list_is_elemlist, 1p == 1) */
extern bool list_is_elemlist(const List* list);
/*lint -sem( list_is_entrylist, 1p == 1) */
extern bool list_is_entrylist(const List* list);
/*lint -sem( list_is_tuplelist, 1p == 1) */
extern bool list_is_tuplelist(const List* list);
/*lint -sem( list_copy, 1p == 1, @P > malloc(1P)) */
extern List* list_copy(const List* list);
/*lint -sem( list_add_list, 1p == 1 && 2p == 1) */
extern void list_add_list(List* list, const List* ll);
/*lint -sem( list_add_elem, 1p == 1 && 2p == 1) */
extern void list_add_elem(List* list, const Elem* elem);
/*lint -sem( list_add_tuple, 1p == 1 && 2p == 1) */
extern void list_add_tuple(List* list, const Tuple* tuple);
/*lint -sem( list_add_entry, 1p == 1 && 2p == 1) */
extern void list_add_entry(List* list, const Entry* entry);
/*lint -sem( list_insert_elem, 1p == 1 && 2p == 1) */
extern void list_insert_elem(List* list, const Elem* elem);
/*lint -sem( list_insert_tuple, 1p == 1 && 2p == 1) */
extern void list_insert_tuple(List* list, const Tuple* tuple);
/*lint -sem( list_insert_entry, 1p == 1 && 2p == 1) */
extern void list_insert_entry(List* list, const Entry* entry);
/*lint -sem( list_get_elems, 1p == 1, @n >= 0) */
extern int list_get_elems(const List* list);
/*lint -sem( list_get_elem, 1p == 1, @P > malloc(1P)) */
extern const Elem* list_get_elem(const List* list, ListElem** idxp);
/*lint -sem( list_get_tuple, 1p == 1, @P > malloc(1P)) */
extern const Tuple* list_get_tuple(const List* list, ListElem** idxp);
/*lint -sem( list_get_entry, 1p == 1, @P > malloc(1P)) */
extern const Entry* list_get_entry(const List* list, ListElem** idxp);
/*lint -sem( list_get_list, 1p == 1, @P > malloc(1P)) */
extern const List* list_get_list(const List* list, ListElem** idxp);
/*lint -sem( list_print, 1p == 1 && 2p == 1) */
extern void list_print(FILE* fp, const List* list);
#ifdef __cplusplus
}
#endif
#endif /* _LIST_H_ */
zimpl-3.3.6/src/zimpl/setprod.c 0000644 0014172 0006025 00000025357 13304236715 016343 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: setprod.c */
/* Name....: Set Product Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/hash.h"
#include "zimpl/set.h"
#include "zimpl/set4.h"
#define SET_PROD_SID 0x53455450
#define SET_PROD_ITER_SID 0x53455049
/* -------------------------------------------------------------------------
* --- valid
* -------------------------------------------------------------------------
*/
static bool set_prod_is_valid(const Set* set)
{
return set != NULL
&& SID_ok2(set->prod, SET_PROD_SID)
&& set->head.refc > 0
&& set->head.dim > 1
&& set->head.members >=0
&& set_is_valid(set->prod.set_a)
&& set_is_valid(set->prod.set_b);
}
static bool set_prod_iter_is_valid(const SetIter* iter)
{
return iter != NULL
&& SID_ok2(iter->prod, SET_PROD_ITER_SID)
&& iter->prod.iter_a != NULL
&& iter->prod.iter_b != NULL;
}
/* -------------------------------------------------------------------------
* --- set_new
* -------------------------------------------------------------------------
*/
Set* set_prod_new(const Set* a, const Set* b)
{
assert(set_is_valid(a));
assert(set_is_valid(b));
assert(a->head.type != SET_PSEUDO);
assert(b->head.type != SET_PSEUDO);
if (a->head.type == SET_EMPTY || b->head.type == SET_EMPTY)
return set_empty_new(a->head.dim + b->head.dim);
Set* set = calloc(1, sizeof(*set));
assert(set != NULL);
set->head.refc = 1;
set->head.dim = a->head.dim + b->head.dim;
set->head.members = a->head.members * b->head.members;
set->head.type = SET_PROD;
set->prod.set_a = set_copy(a);
set->prod.set_b = set_copy(b);
SID_set2(set->prod, SET_PROD_SID);
assert(set_prod_is_valid(set));
return set;
}
/* -------------------------------------------------------------------------
* --- copy
* -------------------------------------------------------------------------
*/
static Set* set_prod_copy(const Set* source)
{
Set* set = (Set*)source;
set->head.refc++;
(void)set_copy(set->prod.set_a);
(void)set_copy(set->prod.set_b);
return set;
}
/* -------------------------------------------------------------------------
* --- set_free
* -------------------------------------------------------------------------
*/
static void set_prod_free(Set* set)
{
assert(set_prod_is_valid(set));
set_free(set->prod.set_a);
set_free(set->prod.set_b);
set->head.refc--;
if (set->head.refc == 0)
{
SID_del2(set->prod);
free(set);
}
}
/* -------------------------------------------------------------------------
* --- lookup
* -------------------------------------------------------------------------
*/
/* Return index number of element. -1 if not present
*/
static SetIterIdx set_prod_lookup_idx(const Set* set, const Tuple* tuple, int offset)
{
assert(set_prod_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset < tuple_get_dim(tuple));
SetIterIdx idx_a = set_lookup_idx(set->prod.set_a, tuple, offset);
if (idx_a < 0)
return -1;
offset += set->prod.set_a->head.dim;
SetIterIdx idx_b = set_lookup_idx(set->prod.set_b, tuple, offset);
if (idx_b < 0)
return -1;
SetIterIdx result = idx_a * set->prod.set_b->head.members + idx_b;
assert(result >= 0); // Check for overflow
return result;
}
/* -------------------------------------------------------------------------
* --- get_tuple
* -------------------------------------------------------------------------
*/
static void set_prod_get_tuple(
const Set* set,
SetIterIdx idx,
Tuple* tuple,
int offset)
{
assert(set_prod_is_valid(set));
assert(idx >= 0);
assert(idx <= set->head.members);
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset + set->head.dim <= tuple_get_dim(tuple));
const Set* a = set->prod.set_a;
const Set* b = set->prod.set_b;
int offset2 = offset + a->head.dim;
set_get_tuple_intern(a, idx / b->head.members, tuple, offset);
set_get_tuple_intern(b, idx % b->head.members, tuple, offset2);
}
/* -------------------------------------------------------------------------
* --- iter_init
* -------------------------------------------------------------------------
*/
/* Initialise Iterator. Write into iter
*/
static SetIter* set_prod_iter_init(
const Set* set,
const Tuple* pattern,
int offset)
{
assert(set_prod_is_valid(set));
assert(pattern == NULL || tuple_is_valid(pattern));
assert(offset >= 0);
assert(pattern == NULL || offset < tuple_get_dim(pattern));
SetIter* iter = calloc(1, sizeof(*iter));
assert(iter != NULL);
iter->prod.elem = calloc((size_t)set->head.dim, sizeof(*iter->prod.elem));
assert(iter->prod.elem != NULL);
iter->prod.first = true;
iter->prod.iter_a = set_iter_init_intern(set->prod.set_a, pattern, offset);
iter->prod.iter_b = set_iter_init_intern(set->prod.set_b, pattern,
offset + set->prod.set_a->head.dim);
SID_set2(iter->prod, SET_PROD_ITER_SID);
assert(set_prod_iter_is_valid(iter));
return iter;
}
/* -------------------------------------------------------------------------
* --- iter_next
* -------------------------------------------------------------------------
*/
/* This gets the fore part of the product and saves it and
* also gets the back part
*/
static bool get_both_parts(
const Set* a,
const Set* b,
SetIter* iter,
SetIter* iter_a,
SetIter* iter_b,
Tuple* tuple,
int offset,
int offset2)
{
if (!set_iter_next_intern(iter_a, a, tuple, offset))
return false;
for(int i = 0; i < a->head.dim; i++)
{
assert(iter->prod.elem[i] == NULL);
iter->prod.elem[i] = elem_copy(tuple_get_elem(tuple, i + offset));
assert(elem_is_valid(iter->prod.elem[i]));
}
if (!set_iter_next_intern(iter_b, b, tuple, offset2))
return false;
return true;
}
/* false means, there is no further element
*/
/*ARGSUSED*/
static bool set_prod_iter_next(
SetIter* iter,
const Set* set,
Tuple* tuple,
int offset)
{
assert(set_prod_iter_is_valid(iter));
assert(set_prod_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset + set->head.dim <= tuple_get_dim(tuple));
Set* a = set->prod.set_a;
Set* b = set->prod.set_b;
SetIter* iter_a = iter->prod.iter_a;
SetIter* iter_b = iter->prod.iter_b;
int offset2 = offset + a->head.dim;
if (iter->prod.first)
{
iter->prod.first = false;
return get_both_parts(a, b, iter, iter_a, iter_b, tuple, offset, offset2);
}
assert(!iter->prod.first);
/* Get back part
*/
if (set_iter_next_intern(iter_b, b, tuple, offset2))
{
/* copy fore part
*/
for(int i = 0; i < a->head.dim; i++)
tuple_set_elem(tuple, i + offset, elem_copy(iter->prod.elem[i]));
return true;
}
/* No back part, so reset it
*/
set_iter_reset_intern(iter_b, b);
/* Clear elem cache
*/
for(int i = 0; i < set->head.dim; i++)
{
if (iter->prod.elem[i] != NULL)
{
elem_free(iter->prod.elem[i]);
iter->prod.elem[i] = NULL;
}
}
return get_both_parts(a, b, iter, iter_a, iter_b, tuple, offset, offset2);
}
/* -------------------------------------------------------------------------
* --- iter_exit
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_prod_iter_exit(SetIter* iter, const Set* set)
{
assert(set_prod_iter_is_valid(iter));
assert(set_prod_is_valid(set));
SID_del2(iter->prod);
set_iter_exit_intern(iter->prod.iter_a, set->prod.set_a);
set_iter_exit_intern(iter->prod.iter_b, set->prod.set_b);
for(int i = 0; i < set->head.dim; i++)
if (iter->prod.elem[i] != NULL)
elem_free(iter->prod.elem[i]);
free(iter->prod.elem);
free(iter);
}
/* -------------------------------------------------------------------------
* --- iter_reset
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_prod_iter_reset(SetIter* iter, const Set* set)
{
assert(set_prod_iter_is_valid(iter));
assert(set_prod_is_valid(set));
iter->prod.first = true;
set_iter_reset_intern(iter->prod.iter_a, set->prod.set_a);
set_iter_reset_intern(iter->prod.iter_b, set->prod.set_b);
}
/* -------------------------------------------------------------------------
* --- vtab_init
* -------------------------------------------------------------------------
*/
void set_prod_init(SetVTab* vtab)
{
vtab[SET_PROD].set_copy = set_prod_copy;
vtab[SET_PROD].set_free = set_prod_free;
vtab[SET_PROD].set_lookup_idx = set_prod_lookup_idx;
vtab[SET_PROD].set_get_tuple = set_prod_get_tuple;
vtab[SET_PROD].iter_init = set_prod_iter_init;
vtab[SET_PROD].iter_next = set_prod_iter_next;
vtab[SET_PROD].iter_exit = set_prod_iter_exit;
vtab[SET_PROD].iter_reset = set_prod_iter_reset;
vtab[SET_PROD].set_is_valid = set_prod_is_valid;
}
zimpl-3.3.6/src/zimpl/elem.h 0000644 0014172 0006025 00000006661 13304236715 015607 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: elem.h */
/* Name....: Element Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _ELEM_H_
#define _ELEM_H_
#ifndef _NUMB_H_
#error "Need to include numb.h before elem.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum element_type
{
ELEM_ERR = 0, ELEM_FREE, ELEM_NUMB, ELEM_STRG, ELEM_NAME
};
typedef enum element_type ElemType;
typedef struct element Elem;
#define ELEM_NULL ((Elem*)0)
extern void elem_init(void);
extern void elem_exit(void);
/*lint -sem( elem_new_numb, @P > malloc(1P)) */
extern Elem* elem_new_numb(const Numb* n);
/*lint -sem( elem_new_strg, nulterm(1), 1p, @P > malloc(1P)) */
extern Elem* elem_new_strg(const char* s);
/*lint -sem( elem_new_name, nulterm(1), 1p, @P > malloc(1P)) */
extern Elem* elem_new_name(const char* s);
/*lint -sem( elem_free, custodial(1), 1p == 1) */
extern void elem_free(Elem* elem);
/*lint -sem( elem_is_valid, 1p == 1) */
extern bool elem_is_valid(const Elem* elem);
/*lint -sem( elem_copy, 1p == 1, @P > malloc(1P)) */
extern Elem* elem_copy(const Elem* elem);
/*lint -sem( elem_cmp, 1p == 1 && 2p == 1) */
extern bool elem_cmp(const Elem* elem_a, const Elem* elem_b);
/*lint -sem( elem_get_type, 1p == 1) */
extern ElemType elem_get_type(const Elem* elem);
/*lint -sem( elem_get_numb, 1p == 1) */
extern const Numb* elem_get_numb(const Elem* elem);
/*lint -sem( elem_get_strg, 1p == 1, @P > malloc(1P) && nulterm(@)) */
extern const char* elem_get_strg(const Elem* elem);
/*lint -sem( elem_get_name, 1p == 1, @P > malloc(1P) && nulterm(@)) */
extern const char* elem_get_name(const Elem* elem);
/*lint -sem( elem_print, 1p == 1 && 2p == 1) */
extern void elem_print(FILE* fp, const Elem* elem, bool use_quotes);
/*lint -sem( elem_hash, 1p == 1) */
extern unsigned int elem_hash(const Elem* elem);
/*lint -sem( elem_tostr, 1p == 1, @P > malloc(1P) && nulterm(@)) */
extern char* elem_tostr(const Elem* elem);
#ifdef __cplusplus
}
#endif
#endif /* _ELEM_H_ */
zimpl-3.3.6/src/zimpl/symbol.c 0000644 0014172 0006025 00000017346 13304236715 016167 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: symbol.c */
/* Name....: Symbol Table Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/entry.h"
#include "zimpl/hash.h"
#include "zimpl/stmt.h"
#include "zimpl/symbol.h"
#define TEST_DUBLICATE 0
#define SYMBOL_SID 0x53796d62
#define SYMBOL_EXTEND_SIZE 100
struct symbol
{
SID
const char* name;
int size;
int used;
int extend;
SymbolType type;
Set* set;
Hash* hash;
Entry** entry;
Entry* deflt;
Symbol* next;
};
static Symbol* anchor = NULL;
Symbol* symbol_new(
const char* name,
SymbolType type,
const Set* set,
int estimated_size,
const Entry* deflt)
{
Symbol* sym;
assert(name != NULL);
assert(strlen(name) > 0);
assert(set != NULL);
assert(estimated_size >= 0);
sym = calloc(1, sizeof(*sym));
assert(sym != NULL);
sym->name = name;
sym->type = type;
sym->size = 1;
sym->used = 0;
sym->extend = SYMBOL_EXTEND_SIZE;
sym->set = set_copy(set);
sym->hash = hash_new(HASH_ENTRY, estimated_size);
sym->entry = calloc(1, sizeof(*sym->entry));
sym->deflt = (deflt != ENTRY_NULL) ? entry_copy(deflt) : ENTRY_NULL;
sym->next = anchor;
anchor = sym;
assert(sym->entry != NULL);
SID_set(sym, SYMBOL_SID);
assert(symbol_is_valid(sym));
return sym;
}
void symbol_exit(void)
{
Symbol* q;
Symbol* p;
int i;
for(p = anchor; p != NULL; p = q)
{
assert(symbol_is_valid(p));
SID_del(p);
q = p->next;
for(i = 0; i < p->used; i++)
entry_free(p->entry[i]);
free(p->entry);
set_free(p->set);
hash_free(p->hash);
if (p->deflt != NULL)
entry_free(p->deflt);
free(p);
}
anchor = NULL;
}
bool symbol_is_valid(const Symbol* sym)
{
if (sym == NULL || !SID_ok(sym, SYMBOL_SID))
return false;
mem_check(sym);
mem_check(sym->entry);
return true;
}
Symbol* symbol_lookup(const char* name)
{
Symbol* sym;
assert(name != NULL);
for(sym = anchor; sym != NULL; sym = sym->next)
if (!strcmp(sym->name, name))
break;
return sym;
}
bool symbol_has_entry(const Symbol* sym, const Tuple* tuple)
{
assert(symbol_is_valid(sym));
assert(tuple_is_valid(tuple));
return hash_has_entry(sym->hash, tuple)
|| (sym->deflt != NULL && set_lookup(sym->set, tuple));
}
/* Liefert NULL wenn nicht gefunden.
* Falls ein default zurueckgegeben wird, stimmt "tuple" nicht mit
* entry->tuple ueberein.
*/
const Entry* symbol_lookup_entry(const Symbol* sym, const Tuple* tuple)
{
const Entry* entry;
assert(symbol_is_valid(sym));
assert(tuple_is_valid(tuple));
entry = hash_lookup_entry(sym->hash, tuple);
if (NULL == entry && sym->deflt != NULL && set_lookup(sym->set, tuple))
entry = sym->deflt;
return entry;
}
/* Entry is eaten.
* No check is done if entry->tuple is a member of sym->set !
* This has to be done before.
*/
void symbol_add_entry(Symbol* sym, Entry* entry)
{
const Tuple* tuple;
assert(symbol_is_valid(sym));
assert(entry_is_valid(entry));
assert(sym->used <= sym->size);
if (sym->used == sym->size)
{
sym->size += sym->extend;
sym->extend += sym->extend;
sym->entry = realloc(
sym->entry, (size_t)sym->size * sizeof(*sym->entry));
assert(sym->entry != NULL);
}
assert(sym->used < sym->size);
tuple = entry_get_tuple(entry);
/* There is no index set for the internal symbol.
*/
assert(!strcmp(sym->name, SYMBOL_NAME_INTERNAL) || set_lookup(sym->set, tuple));
if (hash_has_entry(sym->hash, tuple))
{
if (stmt_trigger_warning(166))
{
fprintf(stderr, "--- Warning 166: Duplicate element ");
tuple_print(stderr, tuple);
fprintf(stderr, " for symbol %s rejected\n", sym->name);
}
entry_free(entry);
}
else
{
/* Falls noch nicht geschehen, legen wir hier den Typ des
* Symbols fest.
*/
if ((sym->type == SYM_ERR) && (sym->used == 0))
sym->type = entry_get_type(entry);
assert(sym->type != SYM_ERR);
hash_add_entry(sym->hash, entry);
sym->entry[sym->used] = entry;
sym->used++;
}
}
int symbol_get_dim(const Symbol* sym)
{
assert(symbol_is_valid(sym));
return set_get_dim(sym->set);
}
const Set* symbol_get_iset(const Symbol* sym)
{
assert(symbol_is_valid(sym));
return sym->set;
}
const char* symbol_get_name(const Symbol* sym)
{
assert(symbol_is_valid(sym));
return sym->name;
}
SymbolType symbol_get_type(const Symbol* sym)
{
assert(symbol_is_valid(sym));
return sym->type;
}
const Numb* symbol_get_numb(const Symbol* sym, int idx)
{
assert(symbol_is_valid(sym));
assert(idx >= 0);
assert(idx < sym->used);
return entry_get_numb(sym->entry[idx]);
}
const char* symbol_get_strg(const Symbol* sym, int idx)
{
assert(symbol_is_valid(sym));
assert(idx >= 0);
assert(idx < sym->used);
return entry_get_strg(sym->entry[idx]);
}
const Set* symbol_get_set(const Symbol* sym, int idx)
{
assert(symbol_is_valid(sym));
assert(idx >= 0);
assert(idx < sym->used);
return entry_get_set(sym->entry[idx]);
}
Var* symbol_get_var(const Symbol* sym, int idx)
{
assert(symbol_is_valid(sym));
assert(idx >= 0);
assert(idx < sym->used);
return entry_get_var(sym->entry[idx]);
}
void symbol_print(FILE* fp, const Symbol* sym)
{
static const char* const type_name[] = { "Error", "Numb", "Strg", "Set", "Var" };
int i;
assert(symbol_is_valid(sym));
fprintf(fp, "Name : %s\n", sym->name);
fprintf(fp, "Type : %s\n", type_name[sym->type]);
fprintf(fp, "Index : ");
set_print(fp, sym->set);
fprintf(fp, "\nEntries:\n");
for(i = 0; i < sym->used; i++)
{
fprintf(fp, "\t%3d: ", i);
entry_print(fp, sym->entry[i]);
fprintf(fp, "\n");
}
fprintf(fp, "\n");
}
void symbol_print_all(FILE* fp)
{
Symbol* sym;
assert(fp != NULL);
for(sym = anchor; sym != NULL; sym = sym->next)
symbol_print(fp, sym);
}
zimpl-3.3.6/src/zimpl/heap.c 0000644 0014172 0006025 00000015430 13304236715 015567 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: heap.c */
/* Name....: Heap Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2006-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/entry.h"
#include "zimpl/heap.h"
#define HEAP_SID 0x48656170
enum heap_type
{
HEAP_ERR = 0, HEAP_ENTRY = 1
};
typedef enum heap_type HeapType;
struct heap
{
SID
HeapType type;
int size; /**< Maximale Anzahl von Elementen im Heap */
int used; /**< Aktuelle Anzahl von Elementen im Heap */
HeapData* data;
HeapCmp data_cmp;
};
static void heap_print(FILE* fp, const Heap* heap)
{
int i;
for(i = 0; i < heap->used; i++)
{
fprintf(fp, "%3d ", i);
switch(heap->type)
{
case HEAP_ENTRY :
entry_print(fp, heap->data[i].entry);
break;
default :
abort();
}
fprintf(fp, "\n");
}
}
bool heap_is_valid(const Heap* heap)
{
HeapData* data;
int i;
if ( heap == NULL
|| heap->type == HEAP_ERR
|| heap->data == NULL
|| heap->data_cmp == NULL
|| heap->size <= 0
|| heap->used < 0
|| heap->used > heap->size)
return false;
data = heap->data;
/* Heap property
*/
for(i = 0; i < heap->used / 2; i++)
{
if ((*heap->data_cmp)(data[i], data[i + i]) > 0)
{
heap_print(stderr, heap);
return false;
}
if (i + i + 1 < heap->used && (*heap->data_cmp)(data[i], data[i + i + 1]) > 0)
{
heap_print(stderr, heap);
return false;
}
}
return true;
}
static Heap* heap_new(
HeapType type,
int size,
HeapCmp data_cmp)
{
Heap* heap = calloc(1, sizeof(*heap));
assert(type == HEAP_ENTRY);
assert(size > 0);
assert(data_cmp != NULL);
assert(heap != NULL);
heap->type = type;
heap->size = size;
heap->used = 0;
heap->data = calloc((size_t)heap->size, sizeof(*heap->data));
heap->data_cmp = data_cmp;
SID_set(heap, HEAP_SID);
assert(heap_is_valid(heap));
return heap;
}
Heap* heap_new_entry(
int size,
HeapCmp heap_entry_cmp)
{
assert(size > 0);
assert(heap_entry_cmp != NULL);
return heap_new(HEAP_ENTRY, size, heap_entry_cmp);
}
void heap_free(Heap* heap)
{
int i;
assert(heap_is_valid(heap));
for(i = 0; i < heap->used; i++)
{
switch(heap->type)
{
case HEAP_ENTRY :
entry_free(heap->data[i].entry);
break;
default :
abort();
}
}
free(heap->data);
free(heap);
}
static void swap_entries(const Heap* heap, int i, int j)
{
HeapData* data = heap->data;
HeapData t;
t = data[i];
data[i] = data[j];
data[j] = t;
}
/* Bewegt einen Eintrag weiter nach unten/hinten im Vektor
* bis die Teilsortierung des Baumes wieder hergestellt ist.
*/
static void sift_down(
const Heap* heap,
int current)
{
HeapData* data = heap->data;
int child;
/* Heap shift down
* (Oberstes Element runter und korrigieren)
*/
child = current * 2;
if (child + 1 < heap->used)
if ((*heap->data_cmp)(data[child + 1], data[child]) < 0)
child++;
while(child < heap->used && (*heap->data_cmp)(data[current], data[child]) > 0)
{
swap_entries(heap, current, child);
current = child;
child += child;
if (child + 1 < heap->used)
if ((*heap->data_cmp)(data[child + 1], data[child]) < 0)
child++;
}
}
/* Bewegt einen Eintrag weiter hoch/nach unten im Vektor
* bis die Teilsortierung des Baumes wieder hergestellt ist.
*/
static void sift_up(
const Heap* heap,
int current)
{
HeapData* data = heap->data;
int parent = current / 2;
/* Heap sift up
*/
while(current > 0 && (*heap->data_cmp)(data[parent], data[current]) > 0)
{
swap_entries(heap, current, parent);
current = parent;
parent /= 2;
}
}
/* Sortiert einen Eintrag in den Heap ein.
*/
void heap_push_entry(
Heap* heap,
Entry* entry)
{
assert(heap_is_valid(heap));
assert(entry_is_valid(entry));
assert(heap->used < heap->size);
heap->data[heap->used].entry = entry;
heap->used++;
sift_up(heap, heap->used - 1);
assert(heap_is_valid(heap));
}
/* Holt den Eintrag mit dem kleinsten Wert aus dem Heap heraus.
*/
Entry* heap_pop_entry(
Heap* heap)
{
Entry* entry;
assert(heap_is_valid(heap));
assert(heap->used > 0);
assert(heap->type == HEAP_ENTRY);
/* Heap shift down
* (Oberstes Element runter und korrigieren)
*/
entry = heap->data[0].entry;
heap->data[0].entry = NULL;
heap->used--;
swap_entries(heap, 0, heap->used);
sift_down(heap, 0);
assert(heap_is_valid(heap));
return entry;
}
const Entry* heap_top_entry(
const Heap* heap)
{
assert(heap_is_valid(heap));
assert(heap->used > 0);
assert(heap->type == HEAP_ENTRY);
return heap->data[0].entry;
}
bool heap_is_full(const Heap* heap)
{
assert(heap_is_valid(heap));
return heap->used == heap->size;
}
bool heap_is_empty(const Heap* heap)
{
assert(heap_is_valid(heap));
return heap->used == 0;
}
zimpl-3.3.6/src/zimpl/define.h 0000644 0014172 0006025 00000005362 13304236715 016114 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: define.h */
/* Name....: Define Table Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _DEFINE_H_
#define _DEFINE_H_
#ifndef _NUMB_H_
#error "Need to include numb.h before define.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum define_type { DEF_ERR = 0, DEF_NUMB, DEF_STRG, DEF_BOOL, DEF_SET };
typedef enum define_type DefineType;
typedef struct define Define;
/*lint -sem( define_new, nulterm(1), 1p) @p == 1 */
extern Define* define_new(const char* name, DefineType type);
/*lint -sem( define_set_param, custodial(2), 1p == 1 && 2p == 1) */
extern void define_set_param(Define* def, Tuple* param);
/*lint -sem( define_set_code, 1p == 1 && 2p == 1) */
extern void define_set_code(Define* def, CodeNode* code);
extern void define_exit(void);
/*lint -sem( define_lookup, nulterm(1), 1p, r_null) */
extern Define* define_lookup(const char* name);
/*lint -sem( define_get_name, 1p == 1, @p && nulterm(@)) */
extern const char* define_get_name(const Define* def);
/*lint -sem( define_get_type, 1p == 1) */
extern DefineType define_get_type(const Define* def);
/*lint -sem( define_get_param, 1p == 1) */
extern const Tuple* define_get_param(const Define* def);
/*lint -sem( define_get_code, 1p == 1) */
extern CodeNode* define_get_code(const Define* def);
#ifdef __cplusplus
}
#endif
#endif /* _DEFINE_H_ */
zimpl-3.3.6/src/zimpl/conname.h 0000644 0014172 0006025 00000003752 13304236715 016303 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: conname.h */
/* Name....: Constraint Names */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _CONNAME_H_
#define _CONNAME_H_
#ifdef __cplusplus
extern "C" {
#endif
enum con_name_format { CON_FORM_MAKE, CON_FORM_NAME, CON_FORM_FULL };
typedef enum con_name_format ConNameForm;
extern void conname_format(ConNameForm format);
extern void conname_free(void);
/*lint -sem( conname_set, nulterm(1), 1p) */
extern bool conname_set(const char* prefix);
/*lint -sem( conname_set, @p && nulterm(@)) */
extern const char* conname_get(void);
extern void conname_next(void);
#ifdef __cplusplus
}
#endif
#endif /* _CONNAME_H_ */
zimpl-3.3.6/src/zimpl/iread.c 0000644 0014172 0006025 00000052142 13304236715 015737 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: iread.c */
/* Name....: Read Instruction */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include
#ifdef WITH_PCRE
#include
#else
#include
#endif
#ifndef _lint
#ifndef WITHOUT_ZLIB
#include
#endif
#else
#include "zimpl/lint.h"
#endif /* _lint */
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/define.h"
#include "zimpl/bound.h"
#include "zimpl/idxset.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/rdefpar.h"
#include "zimpl/conname.h"
#include "zimpl/stmt.h"
#include "zimpl/local.h"
#include "zimpl/list.h"
#include "zimpl/entry.h"
#include "zimpl/heap.h"
#include "zimpl/code.h"
#include "zimpl/inst.h"
#include "zimpl/xlpglue.h"
#include "zimpl/metaio.h"
#include "zimpl/strstore.h"
/* read "datei" as "<1n,3s,12s,4n> %6s" skip 17 use 2000 fs " ;"
*/
#define MAX_FIELDS 65536
CodeNode* i_read_new(CodeNode* self)
{
const char* filename;
const char* pattern;
Trace("i_read_new");
assert(code_is_valid(self));
filename = code_eval_child_strg(self, 0);
pattern = code_eval_child_strg(self, 1);
code_value_rdef(self, rdef_new(filename, pattern));
return self;
}
CodeNode* i_read_param(CodeNode* self)
{
RDef* rdef;
const RPar* rpar;
Trace("i_read_param");
assert(code_is_valid(self));
rdef = rdef_copy(code_eval_child_rdef(self, 0));
rpar = code_eval_child_rpar(self, 1);
rdef_set_param(rdef, rpar);
code_value_rdef(self, rdef);
return self;
}
CodeNode* i_read_comment(CodeNode* self)
{
const char* comment;
Trace("i_read_comment");
assert(code_is_valid(self));
comment = code_eval_child_strg(self, 0);
code_value_rpar(self, rpar_new_comment(comment));
return self;
}
CodeNode* i_read_match(CodeNode* self)
{
const char* match;
Trace("i_read_match");
assert(code_is_valid(self));
match = code_eval_child_strg(self, 0);
code_value_rpar(self, rpar_new_match(match));
return self;
}
CodeNode* i_read_use(CodeNode* self)
{
const Numb* use;
int int_use;
Trace("i_read_use");
assert(code_is_valid(self));
use = code_eval_child_numb(self, 0);
if (!numb_is_int(use))
{
fprintf(stderr, "*** Error 147: use value ");
numb_print(stderr, use);
fprintf(stderr, " is too big or not an integer\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
int_use = numb_toint(use);
if (int_use <= 0)
{
fprintf(stderr, "*** Error 148: use value %d is not positive\n", int_use);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
code_value_rpar(self, rpar_new_use(int_use));
return self;
}
CodeNode* i_read_skip(CodeNode* self)
{
const Numb* skip;
int int_skip;
Trace("i_read_skip");
assert(code_is_valid(self));
skip = code_eval_child_numb(self, 0);
if (!numb_is_int(skip))
{
fprintf(stderr, "*** Error 149: skip value ");
numb_print(stderr, skip);
fprintf(stderr, " is too big or not an integer\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
int_skip = numb_toint(skip);
if (int_skip < 0)
{
fprintf(stderr, "*** Error 150: skip value %d is negative\n", int_skip);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
code_value_rpar(self, rpar_new_skip(int_skip));
return self;
}
static int parse_pattern(
const CodeNode* self,
const char* pattern,
int* param_field,
int* param_type,
bool* is_tuple_list,
bool* is_streaming,
int* hi_field_no)
{
const char* sep = " ,<>";
char* temp = strdup(pattern);
char* s;
char* t;
int field;
char type;
int params = 0;
bool is_single_value = false;
assert(self != NULL);
assert(pattern != NULL);
assert(param_field != NULL);
assert(param_type != NULL);
assert(is_tuple_list != NULL);
assert(hi_field_no != NULL);
*is_streaming = false;
*is_tuple_list = false;
*hi_field_no = 0;
/* Is this a tuple_list "<1n,2s>" or
* an entry_list "<1n,2n> 3s" pattern
* or a single value "2n"
* or a stream "s+" or "n+"
* or a stream tuple list "" or ""
*/
/*lint -e{731} supress "Boolean argument to equal/not equal"
*/
if (( (NULL == strchr(temp, '>')) != (NULL == strchr(temp, '<')))
|| (strrchr(temp, '>') != strchr(temp, '>'))
|| (strrchr(temp, '<') != strchr(temp, '<')))
{
fprintf(stderr, "*** Error 151: Not a valid read template\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
/* Is there an + involved ? Than it is a stream.
*/
if (NULL != strchr(temp, '+'))
{
t = temp;
/* We have a stream template
*/
if (t[0] == '<')
{
if (strlen(t) != 4 || (t[1] != 'n' && t[1] != 's') || t[2] != '+' || t[3] != '>')
{
fprintf(stderr, "*** Error 151: Not a valid read template\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
*is_tuple_list = true;
t++;
t[2] = '\0';
}
if (strlen(t) != 2 || (t[0] != 'n' && t[0] != 's') || t[1] != '+')
{
fprintf(stderr, "*** Error 151: Not a valid read template\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
*is_streaming = true;
param_field[0] = 0;
param_type [0] = t[0];
*hi_field_no = MAX_FIELDS - 1;
free(temp);
return 1;
}
/* Single value or tuple list or entry list ?
*/
s = strchr(temp, '>');
if (NULL == s)
{
/* Single value */
is_single_value = true;
}
else
{
for(++s; isspace(*s); s++)
;
*is_tuple_list = (*s == '\0');
}
/* Here we start to rip the template apart
*/
for(s = strtok(temp, sep);
(s != NULL) && (params < MAX_FIELDS);
s = strtok(NULL, sep))
{
if (2 != sscanf(s, "%d%c", &field, &type))
{
fprintf(stderr, "*** Error 152: Invalid read template syntax\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
field--;
if ((field < 0) || (field >= MAX_FIELDS))
{
fprintf(stderr, "*** Error 153: Invalid field number [%d]\n", field + 1);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
if ((type != 'n') && (type != 's'))
{
fprintf(stderr, "*** Error 154: Invalid field type [%c]\n", type);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
if (field > *hi_field_no)
*hi_field_no = field;
param_field[params] = field;
param_type [params] = type;
params++;
}
free(temp);
if (is_single_value)
{
if (params != 1)
{
fprintf(stderr, "*** Error 201: Invalid read template, only one field allowed\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
}
else if (params - (*is_tuple_list ? 0 : 1) < 1)
{
fprintf(stderr, "*** Error 155: Invalid read template, not enough fields\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
return params;
}
/*lint -sem(split_fields, nulterm(1), 1p && 2n >= 0 && 2n < MAX_FIELDS && 3p, @n >= 0) */
static int split_fields(char* s, int hi_field_no, char* field[])
{
char* t = s;
int fields = 0;
assert(s != NULL);
assert(hi_field_no >= 0);
assert(hi_field_no < MAX_FIELDS);
assert(field != NULL);
for(;;)
{
bool new_field = false;
switch(*s)
{
case '\"' :
s++;
t = s;
while((*s != '\0') && (*s != '\"'))
s++;
new_field = true;
break;
case '\0' :
case '\t' :
case ' ' :
case ',' :
case ';' :
case ':' :
new_field = true;
break;
default :
s++;
break;
}
if (new_field)
{
assert(fields <= hi_field_no);
assert(fields < MAX_FIELDS);
/*xint --e{661} Possible access of out-of-bounds pointer */
char* u = s;
field[fields] = t;
fields++;
if (*s == '\"')
s++;
while(isspace(*s))
s++;
if (*s == ',' || *s == ';' || *s == ':')
s++;
while(isspace(*s))
s++;
*u = '\0';
if (*s == '\0')
break;
/* Have we collected all fields we are interested in?
*/
if (fields - 1 == hi_field_no)
break;
t = s;
}
}
return fields;
}
static List* process_entry_stream(
const CodeNode* self,
List* list,
const RDef* rdef,
int line,
int fields,
char** field,
int param_type) /* param_type[0] */
{
Tuple* tuple;
Entry* entry;
Numb* numb;
int i;
assert(rdef != NULL);
assert(line >= 1);
assert(fields >= 1);
assert(field != NULL);
assert(param_type == 'n' || param_type == 's');
tuple = tuple_new(0);
for(i = 0; i < fields; i++)
{
if (param_type == 'n')
{
if (!numb_is_number(field[i]))
{
fprintf(stderr, "*** Error 174: Numeric field");
fprintf(stderr, " read as \"%s\". This is not a number.\n", field[i]);
fprintf(stderr, "*** File: %s line %d\n",
rdef_get_filename(rdef), line);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
numb = numb_new_ascii(field[i]);
entry = entry_new_numb(tuple, numb);
numb_free(numb);
}
else
{
entry = entry_new_strg(tuple, str_new(field[i]));
}
if (list == NULL)
list = list_new_entry(entry);
else
list_add_entry(list, entry);
entry_free(entry);
}
tuple_free(tuple);
return list;
}
static List* process_tuple_stream(
const CodeNode* self,
List* list,
const RDef* rdef,
int line,
int fields,
char** field,
int param_type) /* param_type[0] */
{
Elem* elem;
Numb* numb;
int i;
assert(rdef != NULL);
assert(line >= 1);
assert(fields >= 1);
assert(field != NULL);
assert(param_type == 'n' || param_type == 's');
for(i = 0; i < fields; i++)
{
Tuple* tuple = tuple_new(1);
if (param_type == 'n')
{
if (!numb_is_number(field[i]))
{
fprintf(stderr, "*** Error 174: Numeric field");
fprintf(stderr, " read as \"%s\". This is not a number.\n", field[i]);
fprintf(stderr, "*** File: %s line %d\n",
rdef_get_filename(rdef), line);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
numb = numb_new_ascii(field[i]);
elem = elem_new_numb(numb);
numb_free(numb);
}
else
{
elem = elem_new_strg(str_new(field[i]));
}
tuple_set_elem(tuple, 0, elem);
if (list == NULL)
list = list_new_tuple(tuple);
else
list_add_tuple(list, tuple);
tuple_free(tuple);
}
return list;
}
static List* process_line(
const CodeNode* self,
List* list,
const RDef* rdef,
int line,
bool is_tuple_list,
int dim,
int fields,
char** field,
const int* param_field,
const int* param_type)
{
Tuple* tuple;
Elem* elem;
Numb* numb;
char* t;
int i;
assert(rdef != NULL);
assert(line >= 1);
assert(dim >= 0);
assert(fields >= 1);
assert(field != NULL);
assert(param_type != NULL);
assert(param_field != NULL);
tuple = tuple_new(dim);
for(i = 0; i < dim; i++)
{
if (param_field[i] >= fields)
{
fprintf(stderr, "*** Error 156: Not enough fields in data\n");
fprintf(stderr, "*** File: %s line %d\n",
rdef_get_filename(rdef), line);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
t = field[param_field[i]];
if (param_type[i] == 'n')
{
if (!numb_is_number(t))
{
fprintf(stderr, "*** Error 174: Numeric field %d", param_field[i] + 1);
fprintf(stderr, " read as \"%s\". This is not a number.\n", t);
fprintf(stderr, "*** File: %s line %d\n",
rdef_get_filename(rdef), line);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
numb = numb_new_ascii(t);
elem = elem_new_numb(numb);
numb_free(numb);
}
else
{
elem = elem_new_strg(str_new(t));
}
tuple_set_elem(tuple, i, elem);
}
if (is_tuple_list)
{
if (list == NULL)
list = list_new_tuple(tuple);
else
list_add_tuple(list, tuple);
}
else
{
Entry* entry;
if (param_field[i] >= fields)
{
fprintf(stderr, "*** Error 157: Not enough fields in data (value)\n");
fprintf(stderr, "*** File: %s line %d\n",
rdef_get_filename(rdef), line);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
t = field[param_field[i]];
if (param_type[i] == 'n')
{
if (!numb_is_number(t))
{
fprintf(stderr, "*** Error 174: Numeric field %d", param_field[i] + 1);
fprintf(stderr, " read as \"%s\". This is not a number.\n", t);
fprintf(stderr, "*** File: %s line %d\n",
rdef_get_filename(rdef), line);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
numb = numb_new_ascii(t);
entry = entry_new_numb(tuple, numb);
numb_free(numb);
}
else
{
entry = entry_new_strg(tuple, str_new(t));
}
if (list == NULL)
list = list_new_entry(entry);
else
list_add_entry(list, entry);
entry_free(entry);
}
tuple_free(tuple);
return list;
}
/* The result of this function is either a tuple_list "<1n,2s>" or
* an entry_list "<2n,3s> 1s" or an elem_list "n+".
* The single value "1s" generates an entry_list.
*/
CodeNode* i_read(CodeNode* self)
{
MFP* fp;
char* buf;
char** field;
int* param_field; /* template parameter field number */
int* param_type; /* template parameter field type */
bool is_tuple_list;
bool is_streaming;
int hi_field_no;
int dim;
const RDef* rdef;
List* list = NULL;
char* filename;
char* comment;
const char* match;
int skip;
int use;
regex_t regex;
Trace("i_read");
assert(code_is_valid(self));
field = malloc(MAX_FIELDS * sizeof(*field));
param_field = malloc(MAX_FIELDS * sizeof(*param_field));
param_type = malloc(MAX_FIELDS * sizeof(*param_type));
assert(field != NULL);
assert(param_field != NULL);
assert(param_type != NULL);
rdef = code_eval_child_rdef(self, 0);
use = rdef_get_use(rdef);
skip = rdef_get_skip(rdef);
dim = parse_pattern(self,
rdef_get_pattern(rdef), param_field, param_type,
&is_tuple_list, &is_streaming, &hi_field_no);
filename = malloc(strlen(rdef_get_filename(rdef)) + 4);
assert(filename != NULL);
strcpy(filename, rdef_get_filename(rdef));
comment = malloc(strlen(rdef_get_comment(rdef)) + 3);
assert(comment != NULL);
comment[0] = '\n';
comment[1] = '\r';
strcpy(&comment[2], rdef_get_comment(rdef));
if (NULL != (match = rdef_get_match(rdef)))
{
int err = regcomp(®ex, match, REG_EXTENDED | REG_NOSUB);
if (err != 0)
{
char errmsg[1024];
regerror(err, ®ex, errmsg, sizeof(errmsg));
fprintf(stderr, "Error 802: %s\n", errmsg);
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
}
/* The last template parameter is the value for the entry_list.
*/
if (!is_tuple_list)
dim--;
if (NULL == (fp = mio_open(filename, ".gz")))
{
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
}
else
{
int line = 0;
if (verbose >= VERB_NORMAL)
printf("Reading %s\n", filename);
while(NULL != (buf = mio_get_line(fp)))
{
char* s;
/* Count the line
*/
line++;
/* Is this a comment line or is there a comment on the line,
* then remove it.
*/
if (NULL != (s = strpbrk(buf, comment)))
*s = '\0';
/* If this is an empty line...
*/
for(s = buf; (*s != '\0') && isspace(*s); s++)
;
/* ... we skip it.
*/
if (*s == '\0')
{
free(buf);
continue;
}
/* do we have regex and if yes it is matched ?
* if not, skip the line.
*/
if (match != NULL && regexec(®ex, s, 0, NULL, 0))
{
free(buf);
continue;
}
/* Should we skip this line ?
*/
if (skip-- > 0)
{
free(buf);
continue;
}
/* Now we break the line in fields.
*/
int fields = split_fields(s, hi_field_no, field);
#if 0
{
int i;
fprintf(stdout, "Fields=%d\n", fields);
for(i = 0; i < fields; i++)
fprintf(stdout, "Field[%d]=[%s]\n", i, field[i]);
}
#endif
if (is_streaming)
{
if (fields == MAX_FIELDS)
{
if (stmt_trigger_warning(213))
{
fprintf(stderr, "--- Warning 213: More than %d input fields in line %d of %s\n",
fields, line, filename);
code_errmsg(self);
}
}
if (is_tuple_list)
list = process_tuple_stream(self, list, rdef, line,
fields, field, param_type[0]);
else
list = process_entry_stream(self, list, rdef, line,
fields, field, param_type[0]);
}
else
{
list = process_line(self, list, rdef, line, is_tuple_list, dim,
fields, field, param_field, param_type);
}
free(buf);
if (--use == 0)
break;
}
mio_close(fp);
}
/* If we found nothing to put into the list, we add a dummy entry
*/
if (list == NULL)
{
Tuple* tuple = tuple_new(0);
if (is_tuple_list)
list = list_new_tuple(tuple);
else
{
Set* set = set_pseudo_new();
Entry* entry = entry_new_set(tuple, set);
list = list_new_entry(entry);
entry_free(entry);
set_free(set);
}
tuple_free(tuple);
/*
fprintf(stderr, "*** Error 158: Read from file found no data\n");
code_errmsg(self);
zpl_exit(EXIT_FAILURE);
*/
}
code_value_list(self, list);
if (match != NULL)
regfree(®ex);
free(comment);
free(filename);
free(param_type);
free(param_field);
free(field);
return self;
}
zimpl-3.3.6/src/zimpl/rdefpar.c 0000644 0014172 0006025 00000013727 13304236715 016304 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: rdefpar.c */
/* Name....: Read Definition / Parameter */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/mme.h"
#include "zimpl/strstore.h"
#include "zimpl/rdefpar.h"
#define RDEF_SID 0x52446566
#define RPAR_SID 0x52506172
enum read_param_type { RPAR_ERR = 0, RPAR_SKIP, RPAR_USE, RPAR_CMNT, RPAR_MTCH };
typedef enum read_param_type RParType;
typedef union read_param_value RParVal;
union read_param_value
{
int i;
const char* s;
};
struct read_param
{
SID
RParType type;
RParVal val;
};
struct read_definition
{
SID
const char* filename;
const char* pattern; /* this was named "template", but template */
const char* comment; /* is a C++ reserved word */
const char* match;
int use;
int skip;
int refc;
};
RDef* rdef_new(const char* filename, const char* pattern)
{
RDef* rdef = calloc(1, sizeof(*rdef));
assert(filename != NULL);
assert(pattern != NULL);
assert(rdef != NULL);
rdef->filename = filename;
rdef->pattern = pattern;
rdef->comment = str_new("");
rdef->match = NULL;
rdef->skip = 0;
rdef->use = -1;
rdef->refc = 1;
SID_set(rdef, RDEF_SID);
assert(rdef_is_valid(rdef));
return rdef;
}
void rdef_free(RDef* rdef)
{
assert(rdef_is_valid(rdef));
rdef->refc--;
if (rdef->refc == 0)
{
SID_del(rdef);
free(rdef);
}
}
bool rdef_is_valid(const RDef* rdef)
{
return ((rdef != NULL)
&& SID_ok(rdef, RDEF_SID)
&& (rdef->filename != NULL)
&& (rdef->pattern != NULL)
&& (rdef->comment != NULL));
}
RDef* rdef_copy(const RDef* source)
{
RDef* rdef = (RDef*)source;
assert(rdef_is_valid(rdef));
rdef->refc++;
return rdef;
}
void rdef_set_param(RDef* rdef, const RPar* rpar)
{
assert(rdef_is_valid(rdef));
assert(rpar_is_valid(rpar));
switch(rpar->type)
{
case RPAR_SKIP :
rdef->skip = rpar->val.i;
break;
case RPAR_USE :
rdef->use = rpar->val.i;
break;
case RPAR_CMNT :
rdef->comment = rpar->val.s;
break;
case RPAR_MTCH :
rdef->match = rpar->val.s;
break;
case RPAR_ERR :
default :
abort();
}
}
const char* rdef_get_filename(const RDef* rdef)
{
assert(rdef_is_valid(rdef));
return rdef->filename;
}
const char* rdef_get_pattern(const RDef* rdef)
{
assert(rdef_is_valid(rdef));
return rdef->pattern;
}
const char* rdef_get_comment(const RDef* rdef)
{
assert(rdef_is_valid(rdef));
return rdef->comment;
}
const char* rdef_get_match(const RDef* rdef)
{
assert(rdef_is_valid(rdef));
return rdef->match;
}
int rdef_get_use(const RDef* rdef)
{
assert(rdef_is_valid(rdef));
return rdef->use;
}
int rdef_get_skip(const RDef* rdef)
{
assert(rdef_is_valid(rdef));
return rdef->skip;
}
/* ----------------------------------------------------------------------------
* Read Parameter
* ----------------------------------------------------------------------------
*/
RPar* rpar_new_skip(int skip)
{
RPar* rpar = calloc(1, sizeof(*rpar));
assert(rpar != NULL);
rpar->type = RPAR_SKIP;
rpar->val.i = skip;
SID_set(rpar, RPAR_SID);
assert(rpar_is_valid(rpar));
return rpar;
}
RPar* rpar_new_use(int use)
{
RPar* rpar = calloc(1, sizeof(*rpar));
assert(rpar != NULL);
rpar->type = RPAR_USE;
rpar->val.i = use;
SID_set(rpar, RPAR_SID);
assert(rpar_is_valid(rpar));
return rpar;
}
RPar* rpar_new_comment(const char* comment)
{
RPar* rpar = calloc(1, sizeof(*rpar));
assert(rpar != NULL);
assert(comment != NULL);
rpar->type = RPAR_CMNT;
rpar->val.s = comment;
SID_set(rpar, RPAR_SID);
assert(rpar_is_valid(rpar));
return rpar;
}
RPar* rpar_new_match(const char* match)
{
RPar* rpar = calloc(1, sizeof(*rpar));
assert(rpar != NULL);
assert(match != NULL);
rpar->type = RPAR_MTCH;
rpar->val.s = match;
SID_set(rpar, RPAR_SID);
assert(rpar_is_valid(rpar));
return rpar;
}
void rpar_free(RPar* rpar)
{
assert(rpar_is_valid(rpar));
SID_del(rpar);
free(rpar);
}
bool rpar_is_valid(const RPar* rpar)
{
return ((rpar != NULL) && SID_ok(rpar, RPAR_SID)
&& (rpar->type != RPAR_ERR));
}
RPar* rpar_copy(const RPar* rpar)
{
RPar* rpnew = calloc(1, sizeof(*rpar));
assert(rpar != NULL);
assert(rpnew != NULL);
rpnew->type = rpar->type;
rpnew->val = rpar->val;
SID_set(rpnew, RPAR_SID);
assert(rpar_is_valid(rpnew));
return rpnew;
}
zimpl-3.3.6/src/zimpl/setpseudo.c 0000644 0014172 0006025 00000016127 13304236715 016671 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: setpseudo.c */
/* Name....: Set Pseudo Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include "zimpl/mshell.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/hash.h"
#include "zimpl/set.h"
#include "zimpl/set4.h"
#define SET_PSEUDO_SID 0x53455452
#define SET_PSEUDO_ITER_SID 0x53455249
/* -------------------------------------------------------------------------
* --- valid
* -------------------------------------------------------------------------
*/
static bool set_pseudo_is_valid(const Set* set)
{
return set != NULL
&& SID_ok2(set->pseudo, SET_PSEUDO_SID)
&& set->head.refc > 0
&& set->head.dim == 0
&& set->head.members == 1;
}
static bool set_pseudo_iter_is_valid(const SetIter* iter)
{
return iter != NULL && SID_ok2(iter->pseudo, SET_PSEUDO_ITER_SID);
}
/* -------------------------------------------------------------------------
* --- set_new
* -------------------------------------------------------------------------
*/
Set* set_pseudo_new()
{
Set* set;
set = calloc(1, sizeof(*set));
assert(set != NULL);
set->head.refc = 1;
set->head.dim = 0;
set->head.members = 1;
set->head.type = SET_PSEUDO;
SID_set2(set->pseudo, SET_PSEUDO_SID);
assert(set_pseudo_is_valid(set));
return set;
}
/* -------------------------------------------------------------------------
* --- copy
* -------------------------------------------------------------------------
*/
static Set* set_pseudo_copy(const Set* source)
{
Set* set = (Set*)source;
set->head.refc++;
return set;
}
/* -------------------------------------------------------------------------
* --- set_free
* -------------------------------------------------------------------------
*/
static void set_pseudo_free(Set* set)
{
assert(set_pseudo_is_valid(set));
set->head.refc--;
if (set->head.refc == 0)
{
SID_del2(set->pseudo);
free(set);
}
}
/* -------------------------------------------------------------------------
* --- lookup
* -------------------------------------------------------------------------
*/
/* Return index number of element. -1 if not present
*/
/*ARGSUSED*/
static SetIterIdx set_pseudo_lookup_idx(const Set* set, const Tuple* tuple, int offset)
{
assert(set_pseudo_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset == 0);
assert(tuple_get_dim(tuple) == 0);
return 0;
}
/* -------------------------------------------------------------------------
* --- get_tuple
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_pseudo_get_tuple(
const Set* set,
SetIterIdx idx,
Tuple* tuple,
int offset)
{
assert(set_pseudo_is_valid(set));
assert(idx == 0);
assert(tuple_is_valid(tuple));
assert(offset == 0);
assert(tuple_get_dim(tuple) == 0);
}
/* -------------------------------------------------------------------------
* --- iter_init
* -------------------------------------------------------------------------
*/
/* Initialise Iterator. Write into iter
*/
/*ARGSUSED*/
static SetIter* iter_init(
const Set* set,
const Tuple* pattern,
int offset)
{
SetIter* iter;
assert(set_pseudo_is_valid(set));
assert(pattern == NULL || tuple_is_valid(pattern));
assert(pattern == NULL || tuple_get_dim(pattern) == 0);
assert(offset == 0);
iter = calloc(1, sizeof(*iter));
assert(iter != NULL);
iter->pseudo.first = true;
SID_set2(iter->pseudo, SET_PSEUDO_ITER_SID);
assert(set_pseudo_iter_is_valid(iter));
return iter;
}
/* -------------------------------------------------------------------------
* --- iter_next
* -------------------------------------------------------------------------
*/
/* false means, there is no further element
*/
/*ARGSUSED*/
static bool iter_next(
SetIter* iter,
UNUSED const Set* set,
UNUSED Tuple* tuple,
UNUSED int offset)
{
assert(set_pseudo_iter_is_valid(iter));
assert(set_pseudo_is_valid(set));
if (!iter->pseudo.first)
return false;
iter->pseudo.first = false;
return true;
}
/* -------------------------------------------------------------------------
* --- iter_exit
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void iter_exit(SetIter* iter, UNUSED const Set* set)
{
assert(set_pseudo_iter_is_valid(iter));
SID_del2(iter->pseudo);
free(iter);
}
/* -------------------------------------------------------------------------
* --- iter_reset
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void iter_reset(SetIter* iter, UNUSED const Set* set)
{
assert(set_pseudo_iter_is_valid(iter));
iter->pseudo.first = true;
}
/* -------------------------------------------------------------------------
* --- vtab_init
* -------------------------------------------------------------------------
*/
void set_pseudo_init(SetVTab* vtab)
{
vtab[SET_PSEUDO].set_copy = set_pseudo_copy;
vtab[SET_PSEUDO].set_free = set_pseudo_free;
vtab[SET_PSEUDO].set_lookup_idx = set_pseudo_lookup_idx;
vtab[SET_PSEUDO].set_get_tuple = set_pseudo_get_tuple;
vtab[SET_PSEUDO].iter_init = iter_init;
vtab[SET_PSEUDO].iter_next = iter_next;
vtab[SET_PSEUDO].iter_exit = iter_exit;
vtab[SET_PSEUDO].iter_reset = iter_reset;
vtab[SET_PSEUDO].set_is_valid = set_pseudo_is_valid;
}
zimpl-3.3.6/src/zimpl/ratlpstore.c 0000644 0014172 0006025 00000125227 13304236715 017057 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: lpstore.c */
/* Name....: Store Linear Programm */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2003-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include
#include "zimpl/mshell.h"
#include "zimpl/gmpmisc.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/bound.h"
#include "zimpl/mme.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/ratlp.h"
#include "zimpl/ratlpstore.h"
#ifdef _MSC_VER
#pragma warning (disable: 4100)
#endif
#define LPF_NAME_LEN 16
#define MPS_NAME_LEN 8
#define PIP_NAME_LEN 255
#define MIN_NAME_LEN 8
struct storage
{
unsigned int size;
Nzo* begin;
Sto* next;
};
static const unsigned int sto_size = 1000;
#ifndef LHT_BUCKETS
#define LHT_BUCKETS 1000003U
#endif
enum lps_hash_type { LHT_ERR = 0, LHT_VAR, LHT_CON, LHT_SOS };
typedef struct lps_hash_element LpsHElem;
typedef enum lps_hash_type LpsHashType;
struct lps_hash_element
{
LpsHElem* next;
union
{
Con* con;
Var* var;
Sos* sos;
} value;
};
struct lps_hash
{
unsigned int size;
int elems;
LpsHashType type;
LpsHElem** bucket;
};
static void hash_statist(FILE* fp, const LpsHash* hash); //lint !e528 not referenced
static bool hash_valid(const LpsHash* hash)
{
return hash != NULL
&& (hash->type == LHT_CON || hash->type == LHT_VAR || hash->type == LHT_SOS);
}
static unsigned int hashit(const char* s)
{
unsigned int hcode = 0;
/* I am not too sure this works well for 64bit integers.
*/
/*lint -e{506} supress "Constant value Boolean"
*/
assert(sizeof(hcode) == 4);
for(; *s != '\0'; s++)
hcode = 31 * hcode + (unsigned char)*s;
return hcode;
}
static LpsHash* lps_hash_new(LpsHashType type)
{
LpsHash* hash = calloc(1, sizeof(*hash));
assert(hash != NULL);
hash->size = LHT_BUCKETS;
hash->elems = 0;
hash->type = type;
hash->bucket = calloc(hash->size, sizeof(*hash->bucket));
assert(hash->bucket != NULL);
assert(hash_valid(hash));
return hash;
}
static void lps_hash_free(LpsHash* hash)
{
LpsHElem* he;
LpsHElem* hq;
unsigned int i;
assert(hash_valid(hash));
#if 0
#ifndef NDEBUG
hash_statist(stdout, hash);
#endif
#endif
for(i = 0; i < hash->size; i++)
{
for(he = hash->bucket[i]; he != NULL; he = hq)
{
hq = he->next;
free(he);
}
}
free(hash->bucket);
free(hash);
}
/* Liefert NULL wenn nicht gefunden.
*/
static Var* hash_lookup_var(const LpsHash* hash, const char* name)
{
unsigned int hcode;
LpsHElem* he;
assert(hash_valid(hash));
assert(hash->type == LHT_VAR);
assert(name != NULL);
hcode = hashit(name) % hash->size;
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (!strcmp(he->value.var->name, name))
break;
return (he == NULL) ? (Var*)0 : he->value.var;
}
/* Liefert NULL wenn nicht gefunden.
*/
static Con* hash_lookup_con(const LpsHash* hash, const char* name)
{
unsigned int hcode;
LpsHElem* he;
assert(hash_valid(hash));
assert(hash->type == LHT_CON);
assert(name != NULL);
hcode = hashit(name) % hash->size;
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (!strcmp(he->value.con->name, name))
break;
return (he == NULL) ? (Con*)0 : he->value.con;
}
/* Liefert NULL wenn nicht gefunden.
*/
static Sos* hash_lookup_sos(const LpsHash* hash, const char* name)
{
unsigned int hcode;
LpsHElem* he;
assert(hash_valid(hash));
assert(hash->type == LHT_SOS);
assert(name != NULL);
hcode = hashit(name) % hash->size;
for(he = hash->bucket[hcode]; he != NULL; he = he->next)
if (!strcmp(he->value.sos->name, name))
break;
return (he == NULL) ? (Sos*)0 : he->value.sos;
}
static void hash_add_var(LpsHash* hash, Var* var)
{
LpsHElem* he = calloc(1, sizeof(*he));
unsigned int hcode;
assert(hash_valid(hash));
assert(var != NULL);
assert(hash->type == LHT_VAR);
assert(he != NULL);
hcode = hashit(var->name) % hash->size;
he->value.var = var;
he->next = hash->bucket[hcode];
hash->bucket[hcode] = he;
hash->elems++;
assert(hash_lookup_var(hash, var->name) == var);
}
static void hash_del_var(LpsHash* hash, const Var* var)
{
LpsHElem* he;
LpsHElem* next;
unsigned int hcode;
assert(hash_valid(hash));
assert(var != NULL);
assert(hash->type == LHT_VAR);
hcode = hashit(var->name) % hash->size;
for(he = hash->bucket[hcode], next = NULL; he != NULL; next = he, he = he->next)
if (he->value.var == var)
break;
assert(he != NULL);
if (next == NULL)
hash->bucket[hcode] = he->next;
else
next->next = he->next;
hash->elems--;
free(he);
assert(hash_valid(hash));
}
static void hash_add_con(LpsHash* hash, Con* con)
{
LpsHElem* he = calloc(1, sizeof(*he));
unsigned int hcode;
assert(hash_valid(hash));
assert(con != NULL);
assert(hash->type == LHT_CON);
assert(he != NULL);
hcode = hashit(con->name) % hash->size;
he->value.con = con;
he->next = hash->bucket[hcode];
hash->bucket[hcode] = he;
hash->elems++;
assert(hash_lookup_con(hash, con->name) == con);
}
static void hash_add_sos(LpsHash* hash, Sos* sos)
{
LpsHElem* he = calloc(1, sizeof(*he));
unsigned int hcode;
assert(hash_valid(hash));
assert(sos != NULL);
assert(hash->type == LHT_SOS);
assert(he != NULL);
hcode = hashit(sos->name) % hash->size;
he->value.sos = sos;
he->next = hash->bucket[hcode];
hash->bucket[hcode] = he;
hash->elems++;
assert(hash_lookup_sos(hash, sos->name) == sos);
}
static void hash_del_con(LpsHash* hash, const Con* con)
{
LpsHElem* he;
LpsHElem* next;
unsigned int hcode;
assert(hash_valid(hash));
assert(con != NULL);
assert(hash->type == LHT_CON);
hcode = hashit(con->name) % hash->size;
for(he = hash->bucket[hcode], next = NULL; he != NULL; next = he, he = he->next)
if (he->value.con == con)
break;
assert(he != NULL);
if (next == NULL)
hash->bucket[hcode] = he->next;
else
next->next = he->next;
hash->elems--;
free(he);
assert(hash_valid(hash));
}
static void hash_statist(FILE* fp, const LpsHash* hash) //lint !e528 not referenced
{
assert(fp != NULL);
assert(hash_valid(hash));
LpsHElem* he;
int min = (int)hash->size;
int max = 0;
int sum = 0;
int zeros = 0;
int filled = 0;
double avg = 0.0;
for(unsigned int i = 0; i < hash->size; i++)
{
int count = 0;
for(he = hash->bucket[i]; he != NULL; he = he->next)
count++;
if (count == 0)
zeros++;
else
filled++;
if (count < min)
min = count;
if (count > max)
max = count;
sum += count;
}
assert(sum == hash->elems);
if (filled > 0)
avg = (double)sum / (double)filled;
fprintf(fp,
"HashStat: size=%u sum=%d min=%d max=%d avg=%.1f zero=%d filled=%d\n",
hash->size, sum, min, max, avg, zeros, filled);
}
#ifndef NDEBUG
static bool lps_valid(const Lps* lp)
{
const char* err1 = "Wrong Previous Variable";
const char* err2 = "Wrong Variable Previous Nonzero";
const char* err3 = "Wrong Variable Nonzero Count";
const char* err4 = "Wrong Variable Count";
const char* err5 = "Wrong Previous Constraint";
const char* err6 = "Wrong Constraint Previous Nonzero";
const char* err7 = "Wrong Constraint Nonzero Count";
const char* err8 = "Wrong Constraint Count";
const char* err9 = "Wrong Variable";
const char* err10 = "Wrong Constraint";
const char* err11 = "Storage-size error";
const char* err12 = "Wrong Variable SID";
const char* err13 = "Wrong Constraint SID";
const char* err14 = "Strange lhs/rhs";
const char* err15 = "Wrong SOS SID";
const char* err16 = "Wrong SOS Variable SID";
const char* err18 = "Wrong SOS element count";
const char* err19 = "Wrong SOS count";
assert(lp != NULL);
Var* var;
Var* var_prev;
Con* con;
Con* con_prev;
Nzo* nzo;
Nzo* nzo_prev;
Sto* sto;
Sos* sos;
Sse* sse;
int var_count;
int con_count;
int nzo_count;
int sto_count;
int sos_count;
int sse_count;
/* Variable Test
*/
var_count = lp->vars;
for(var = lp->var_root, var_prev = NULL; var != NULL; var = var->next)
{
if (var->sid != VAR_SID)
{
fprintf(stderr, "%s\n", err12);
return false;
}
if (var_prev == var->prev)
var_prev = var;
else
{
fprintf(stderr, "%s\n", err1);
return false;
}
var_count--;
nzo_count = var->size;
for(nzo = var->first, nzo_prev = NULL; nzo != NULL; nzo = nzo->var_next)
{
if (nzo_prev == nzo->var_prev)
nzo_prev = nzo;
else
{
fprintf(stderr, "%s\n", err2);
return false;
}
if (nzo->var != var)
{
fprintf(stderr, "%s\n", err9);
return false;
}
nzo_count--;
}
if (nzo_count)
{
fprintf(stderr, "%s\n", err3);
return false;
}
}
if (var_count)
{
fprintf(stderr, "%s\n", err4);
return false;
}
/* Constraint Test
*/
con_count = lp->cons;
for(con = lp->con_root, con_prev = NULL; con != NULL; con = con->next)
{
if (con->sid != CON_SID)
{
fprintf(stderr, "%s\n", err13);
return false;
}
if (con_prev == con->prev)
con_prev = con;
else
{
fprintf(stderr, "%s\n", err5);
return false;
}
switch(con->type)
{
case CON_FREE :
case CON_LHS :
case CON_RHS :
break;
case CON_RANGE :
if (mpq_cmp(con->lhs, con->rhs) >= 0)
{
fprintf(stderr, "%s %s %g %g\n",
err14, con->name, mpq_get_d(con->lhs), mpq_get_d(con->rhs));
return false;
}
break;
case CON_EQUAL :
if (!mpq_equal(con->lhs, con->rhs))
{
fprintf(stderr, "%s %s %g %g\n",
err14, con->name, mpq_get_d(con->lhs), mpq_get_d(con->rhs));
return false;
}
break;
default :
abort();
}
con_count--;
nzo_count = con->size;
for(nzo = con->first, nzo_prev = NULL; nzo != NULL; nzo = nzo->con_next)
{
if (nzo_prev == nzo->con_prev)
nzo_prev = nzo;
else
{
fprintf(stderr, "%s\n", err6);
return false;
}
if (nzo->con != con)
{
fprintf(stderr, "%s\n", err10);
return false;
}
nzo_count--;
}
if (nzo_count)
{
fprintf(stderr, "%s\n", err7);
return false;
}
}
if (con_count)
{
fprintf(stderr, "%s\n", err8);
return false;
}
/* SOS Test
*/
sos_count = lp->soss;
for(sos = lp->sos_root; sos != NULL; sos = sos->next)
{
if (sos->sid != SOS_SID)
{
fprintf(stderr, "%s\n", err15);
return false;
}
sos_count--;
sse_count = sos->sses;
for(sse = sos->first; sse != NULL; sse = sse->next)
{
if (sse->var->sid != VAR_SID)
{
fprintf(stderr, "%s\n", err16);
return false;
}
sse_count--;
}
if (sse_count)
{
fprintf(stderr, "%s\n", err18);
return false;
}
}
if (sos_count)
{
fprintf(stderr, "%s\n", err19);
return false;
}
/* Storage Test
*/
sto_count = 0;
for(sto = lp->sto_root; sto != NULL; sto = sto->next)
{
assert(sto->begin != NULL);
sto_count++;
}
if (sto_count * (int)sto_size < lp->nonzeros)
{
fprintf(stderr, "%s %d %u %d\n",
err11, sto_count, sto_size, lp->nonzeros);
return false;
}
return true;
}
#endif /* !NDEBUG */
static void lps_storage(Lps* lp)
{
Sto* s;
Nzo* n;
unsigned int i;
assert(lps_valid(lp));
assert(lp->next == NULL);
s = malloc(sizeof(*s));
assert(s != NULL);
n = malloc(sto_size * sizeof(*n));
assert(n != NULL);
for(i = 0; i < sto_size - 1; i++)
{
n[i].var_next = &n[i + 1];
mpq_init(n[i].value);
#ifndef NDEBUG
n[i].var_prev = NULL;
n[i].con_next = NULL;
n[i].con_prev = NULL;
n[i].var = NULL;
n[i].con = NULL;
#endif
}
n[i].var_next = NULL;
mpq_init(n[i].value);
#ifndef NDEBUG
n[i].var_prev = NULL;
n[i].con_next = NULL;
n[i].con_prev = NULL;
n[i].var = NULL;
n[i].con = NULL;
#endif
s->size = sto_size;
s->begin = n;
s->next = lp->sto_root;
lp->sto_root = s;
lp->next = s->begin;
}
Lps* lps_alloc(
const char* name)
{
Lps* lp;
assert(name != NULL);
lp = malloc(sizeof(*lp));
assert(lp != NULL);
lp->name = strdup(name);
lp->probname = NULL;
lp->objname = NULL;
lp->rhsname = NULL;
lp->bndname = NULL;
lp->rngname = NULL;
lp->type = LP_LP;
lp->direct = LP_MIN;
lp->vars = 0;
lp->cons = 0;
lp->soss = 0;
lp->nonzeros = 0;
lp->var_root = NULL;
lp->con_root = NULL;
lp->sos_root = NULL;
lp->sto_root = NULL;
lp->next = NULL;
lp->var_hash = lps_hash_new(LHT_VAR);
lp->con_hash = lps_hash_new(LHT_CON);
lp->sos_hash = lps_hash_new(LHT_SOS);
lp->var_last = NULL;
lp->con_last = NULL;
lp->sos_last = NULL;
lp->name_len = 0;
assert(lps_valid(lp));
return lp;
}
void lps_free(Lps* lp)
{
Var* var;
Var* var_next;
Con* con;
Con* con_next;
Sos* sos;
Sos* sos_next;
Sse* sse;
Sse* sse_next;
Sto* sto;
Sto* sto_next;
unsigned int i;
assert(lps_valid(lp));
lps_hash_free(lp->var_hash);
lps_hash_free(lp->con_hash);
lps_hash_free(lp->sos_hash);
for(sto = lp->sto_root; sto != NULL; sto = sto_next)
{
for(i = 0; i < sto_size; i++)
mpq_clear(sto->begin[i].value);
sto_next = sto->next;
free(sto->begin);
free(sto);
}
for(var = lp->var_root; var != NULL; var = var_next)
{
var_next = var->next;
var->sid = 0x0;
mpq_clear(var->cost);
mpq_clear(var->lower);
mpq_clear(var->upper);
mpq_clear(var->value);
mpq_clear(var->startval);
free(var->name);
free(var);
}
for(con = lp->con_root; con != NULL; con = con_next)
{
Qme* qme;
Qme* qme_next;
con_next = con->next;
con->sid = 0x0;
for(qme = con->qme_first; qme != NULL; qme = qme_next)
{
qme_next = qme->next;
mpq_clear(qme->value);
free(qme);
}
mpq_clear(con->lhs);
mpq_clear(con->rhs);
mpq_clear(con->scale);
if (con->term != NULL)
term_free(con->term);
free(con->name);
free(con);
}
for(sos = lp->sos_root; sos != NULL; sos = sos_next)
{
sos_next = sos->next;
sos->sid = 0x0;
for(sse = sos->first; sse != NULL; sse = sse_next)
{
sse_next = sse->next;
mpq_clear(sse->weight);
free(sse);
}
free(sos->name);
free(sos);
}
if (lp->probname != NULL)
free(lp->probname);
if (lp->objname != NULL)
free(lp->objname);
if (lp->rhsname != NULL)
free(lp->rhsname);
if (lp->bndname != NULL)
free(lp->bndname);
if (lp->rngname != NULL)
free(lp->rngname);
free(lp->name);
free(lp);
}
void lps_number(const Lps* lp)
{
Var* var;
Con* con;
int i;
assert(lps_valid(lp));
for(var = lp->var_root, i = 0; var != NULL; var = var->next, i++)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
var->number = i;
}
assert(i == lp->vars);
for(con = lp->con_root, i = 0; con != NULL; con = con->next, i++)
{
assert(con != NULL);
assert(con->sid == CON_SID);
con->number = i;
}
assert(i == lp->cons);
}
Var* lps_getvar(
const Lps* lp,
const char* name)
{
Var* vr;
assert(lps_valid(lp));
assert(name != NULL);
vr = hash_lookup_var(lp->var_hash, name);
assert((vr == NULL) || (vr->sid == VAR_SID));
assert((vr == NULL) || (!strcmp(vr->name, name)));
#ifndef NDEBUG
{
const Var* var;
for(var = lp->var_root; var != NULL; var = var->next)
if (!strcmp(var->name, name))
break;
assert(var == vr);
}
#endif
return vr;
}
Con* lps_getcon(
const Lps* lp,
const char* name)
{
Con* cr;
assert(lps_valid(lp));
assert(name != NULL);
cr = hash_lookup_con(lp->con_hash, name);
assert((cr == NULL) || (cr->sid == CON_SID));
assert((cr == NULL) || (!strcmp(cr->name, name)));
#ifndef NDEBUG
{
const Con* con;
for(con = lp->con_root; con != NULL; con = con->next)
if (!strcmp(con->name, name))
break;
assert(con == cr);
}
#endif
return cr;
}
Sos* lps_getsos(
const Lps* lp,
const char* name)
{
Sos* sr;
assert(lps_valid(lp));
assert(name != NULL);
sr = hash_lookup_sos(lp->sos_hash, name);
assert((sr == NULL) || (sr->sid == VAR_SID));
assert((sr == NULL) || (!strcmp(sr->name, name)));
#ifndef NDEBUG
{
const Sos* sos;
for(sos = lp->sos_root; sos != NULL; sos = sos->next)
if (!strcmp(sos->name, name))
break;
assert(sos == sr);
}
#endif
return sr;
}
Nzo* lps_getnzo(
const Lps* lp,
const Con* con,
const Var* var)
{
Nzo* nzo;
assert(lps_valid(lp));
assert(con != NULL);
assert(con->sid == CON_SID);
assert(var != NULL);
assert(var->sid == VAR_SID);
/* Whatever is shorter
*/
if (var->size <= con->size)
{
for(nzo = var->first; nzo != NULL; nzo = nzo->var_next)
if (nzo->con == con)
break;
}
else
{
for(nzo = con->first; nzo != NULL; nzo = nzo->con_next)
if (nzo->var == var)
break;
}
assert((nzo == NULL) || ((nzo->var == var) && (nzo->con == con)));
return nzo;
}
Var* lps_addvar(
Lps* lp,
const char* name)
{
Var* v;
assert(lps_valid(lp));
assert(name != NULL);
assert(lps_getvar(lp, name) == NULL);
v = malloc(sizeof(*v));
assert(v != NULL);
mpq_init(v->cost);
mpq_init(v->lower);
mpq_init(v->upper);
mpq_init(v->value);
mpq_init(v->startval);
v->sid = VAR_SID;
v->name = strdup(name);
v->number = lp->vars;
v->vclass = VAR_CON;
v->type = VAR_FREE;
v->is_used = false;
v->priority = 0;
v->size = 0;
v->first = NULL;
v->next = NULL;
v->prev = lp->var_last;
lp->var_last = v;
if (v->prev == NULL)
lp->var_root = v;
else
{
assert(v->prev->next == NULL);
v->prev->next = v;
}
lp->vars++;
hash_add_var(lp->var_hash, v);
assert(lps_valid(lp));
return v;
}
void lps_delvar(
Lps* lp,
Var* var)
{
assert(lps_valid(lp));
/* remove non-zeros
*/
while(var->first != NULL)
lps_delnzo(lp, var->first);
assert(var->size == 0);
/* Correkt "next" links
*/
if (var->prev != NULL)
{
var->prev->next = var->next;
assert(lp->var_root != var);
}
else
{
assert(lp->var_root == var);
lp->var_root = var->next;
assert(lp->var_root != NULL || lp->vars == 0);
}
/* Correkt "prev" links
*/
if (var->next != NULL)
{
var->next->prev = var->prev;
assert(lp->var_last != var);
}
else
{
assert(lp->var_last == var);
lp->var_last = var->prev;
assert(lp->var_last != NULL || lp->vars == 0);
}
hash_del_var(lp->var_hash, var);
mpq_clear(var->cost);
mpq_clear(var->lower);
mpq_clear(var->upper);
mpq_clear(var->value);
mpq_clear(var->startval);
var->sid = 0;
free(var->name);
free(var);
lp->vars--;
assert(lps_valid(lp));
}
Con* lps_addcon(
Lps* lp,
const char* name)
{
Con* c;
assert(lps_valid(lp));
assert(name != NULL);
assert(lps_getcon(lp, name) == NULL);
c = calloc(1, sizeof(*c));
assert(c != NULL);
mpq_init(c->lhs);
mpq_init(c->rhs);
mpq_init(c->scale);
c->sid = CON_SID;
c->name = strdup(name);
c->number = lp->cons;
c->size = 0;
c->type = CON_FREE;
c->flags = 0;
c->ind_var = NULL;
c->ind_dir = true;
c->first = NULL;
c->qme_first = NULL;
c->term = NULL;
c->next = NULL;
c->prev = lp->con_last;
lp->con_last = c;
if (c->prev == NULL)
lp->con_root = c;
else
{
assert(c->prev->next == NULL);
c->prev->next = c;
}
lp->cons++;
hash_add_con(lp->con_hash, c);
assert(lps_valid(lp));
return c;
}
void lps_delcon(
Lps* lp,
Con* con)
{
assert(lps_valid(lp));
/* remove non-zeros
*/
while(con->first != NULL)
lps_delnzo(lp, con->first);
assert(con->size == 0);
/* Correkt "next" links
*/
if (con->prev != NULL)
{
con->prev->next = con->next;
assert(lp->con_root != con);
}
else
{
assert(lp->con_root == con);
lp->con_root = con->next;
assert(lp->con_root != NULL || lp->cons == 0);
}
/* Correkt "prev" links
*/
if (con->next != NULL)
{
con->next->prev = con->prev;
assert(lp->con_last != con);
}
else
{
assert(lp->con_last == con);
lp->con_last = con->prev;
assert(lp->con_last != NULL || lp->cons == 0);
}
hash_del_con(lp->con_hash, con);
con->sid = 0x0;
mpq_clear(con->lhs);
mpq_clear(con->rhs);
mpq_clear(con->scale);
free(con->name);
free(con);
lp->cons--;
/* ??? qme_first term ? */
assert(lps_valid(lp));
}
Sos* lps_addsos(
Lps* lp,
const char* name,
SosType type,
int priority)
{
Sos* sos;
assert(lps_valid(lp));
assert(name != NULL);
assert(lps_getsos(lp, name) == NULL);
sos = malloc(sizeof(*sos));
assert(sos != NULL);
sos->sid = SOS_SID;
sos->name = strdup(name);
sos->type = type;
sos->priority = priority;
sos->sses = 0;
sos->first = NULL;
sos->next = NULL;
if (lp->sos_last != NULL)
lp->sos_last->next = sos;
lp->sos_last = sos;
if (lp->sos_root == NULL)
lp->sos_root = sos;
lp->soss++;
hash_add_sos(lp->sos_hash, sos);
assert(lps_valid(lp));
return sos;
}
/*ARGSUSED*/
void lps_addqme(
UNUSED Lps* lp,
Con* con,
Var* var1,
Var* var2,
const mpq_t value)
{
Qme* qme = malloc(sizeof(*qme));
assert(qme != NULL);
qme->sid = QME_SID;
qme->var1 = var1;
qme->var2 = var2;
mpq_init(qme->value);
mpq_set(qme->value, value);
qme->next = con->qme_first;
con->qme_first = qme;
var1->is_used = true;
var2->is_used = true;
}
/*ARGSUSED*/
void lps_addterm(
UNUSED Lps* lp,
Con* con,
const Term* term)
{
int i;
int k;
assert(con != NULL);
/* assert(term_valid(term));*/
assert(con->term == NULL);
con->term = term_copy(term);
for(i = 0; i < term_get_elements(term); i++)
{
const Mono* mono = term_get_element(term, i);
for(k = 0; k < mono_get_degree(mono); k++)
mono_get_var(mono, k)->is_used = true;
}
}
void lps_addsse(
Sos* sos,
Var* var,
const mpq_t weight)
{
Sse* sse;
assert(sos != NULL);
assert(sos->sid == SOS_SID);
assert(var != NULL);
assert(var->sid == VAR_SID);
sse = malloc(sizeof(*sse));
assert(sse != NULL);
mpq_init(sse->weight);
mpq_set(sse->weight, weight);
sse->var = var;
sse->next = sos->first;
sos->first = sse;
sos->sses++;
sse->var->is_used = true;
}
void lps_addnzo(
Lps* lp,
Con* con,
Var* var,
const mpq_t value)
{
Nzo* nzo;
assert(lps_valid(lp));
assert(con != NULL);
assert(con->sid == CON_SID);
assert(var != NULL);
assert(var->sid == VAR_SID);
/* Ins LP aufnehmen
*/
if (lp->next == NULL)
lps_storage(lp);
nzo = lp->next;
assert(nzo != NULL);
lp->next = nzo->var_next;
lp->nonzeros++;
mpq_set(nzo->value, value);
/* In die Spalte aufnehmen
*/
nzo->var = var;
nzo->var_prev = NULL;
nzo->var_next = var->first;
var->first = nzo;
var->size++;
if (nzo->var_next != NULL)
{
assert(nzo->var_next->var_prev == NULL);
nzo->var_next->var_prev = nzo;
}
/* In die Zeile aufnehmen
*/
nzo->con = con;
nzo->con_prev = NULL;
nzo->con_next = con->first;
con->first = nzo;
con->size++;
if (nzo->con_next != NULL)
{
assert(nzo->con_next->con_prev == NULL);
nzo->con_next->con_prev = nzo;
}
assert(lps_valid(lp));
}
void lps_delnzo(
Lps* lp,
Nzo* nzo)
{
assert(lps_valid(lp));
assert(nzo != NULL);
/* Aus der Spalte nahmen
*/
if (nzo == nzo->var->first)
nzo->var->first = nzo->var_next;
if (nzo->var_prev != NULL)
nzo->var_prev->var_next = nzo->var_next;
if (nzo->var_next != NULL)
nzo->var_next->var_prev = nzo->var_prev;
nzo->var->size--;
/* Aus der Zeile nahmen
*/
if (nzo == nzo->con->first)
nzo->con->first = nzo->con_next;
if (nzo->con_prev != NULL)
nzo->con_prev->con_next = nzo->con_next;
if (nzo->con_next != NULL)
nzo->con_next->con_prev = nzo->con_prev;
nzo->con->size--;
/* Aus dem LP nehmen
*/
nzo->var_next = lp->next;
lp->next = nzo;
lp->nonzeros--;
assert(lps_valid(lp));
}
void lps_setval(
Nzo* nzo,
const mpq_t value)
{
assert(nzo != NULL);
mpq_set(nzo->value, value);
}
void lps_getval(
const Nzo* nzo,
mpq_t value)
{
assert(nzo != NULL);
mpq_set(value, nzo->value);
}
void lps_setdir(
Lps* lp,
LpDirect direct)
{
assert(lps_valid(lp));
lp->direct = direct;
}
void lps_setprobname(
Lps* lp,
const char* name)
{
assert(lp != NULL);
assert(name != NULL);
if (lp->probname != NULL)
free(lp->probname);
lp->probname = strdup(name);
}
bool lps_setobjname(
Lps* lp,
const char* name)
{
assert(lp != NULL);
assert(name != NULL);
bool is_not_empty = lp->objname != NULL;
if (is_not_empty)
free(lp->objname);
lp->objname = strdup(name);
return is_not_empty;
}
void lps_setrhsname(
Lps* lp,
const char* name)
{
assert(lp != NULL);
assert(name != NULL);
if (lp->rhsname != NULL)
free(lp->rhsname);
lp->rhsname = strdup(name);
}
void lps_setbndname(
Lps* lp,
const char* name)
{
assert(lp != NULL);
assert(name != NULL);
if (lp->bndname != NULL)
free(lp->bndname);
lp->bndname = strdup(name);
}
void lps_setrngname(
Lps* lp,
const char* name)
{
assert(lp != NULL);
assert(name != NULL);
if (lp->rngname != NULL)
free(lp->rngname);
lp->rngname = strdup(name);
}
void lps_getcost(
const Var* var,
mpq_t cost)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
mpq_set(cost, var->cost);
}
bool lps_haslower(const Var* var)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
return HAS_LOWER(var);
}
void lps_setcost(
Var* var,
const mpq_t cost)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
mpq_set(var->cost, cost);
}
void lps_getlower(const Var* var, mpq_t lower)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
mpq_set(lower, var->lower);
}
void lps_setlower(
Var* var,
const mpq_t lower)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
mpq_set(var->lower, lower);
/* FREE -> LOWER
* LOWER -> LOWER
* UPPER -> BOXED/FIXED
* BOXED -> BOXED/FIXED
* FIXED -> BOXED/FIXED
*/
if (var->type == VAR_FREE)
var->type = VAR_LOWER;
else if (var->type != VAR_LOWER)
{
assert(var->type == VAR_UPPER || var->type == VAR_BOXED || var->type == VAR_FIXED);
var->type = mpq_equal(var->lower, var->upper) ? VAR_FIXED : VAR_BOXED;
}
}
bool lps_hasupper(const Var* var)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
return HAS_UPPER(var);
}
void lps_getupper(const Var* var, mpq_t upper)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
mpq_set(upper, var->upper);
}
void lps_setupper(
Var* var,
const mpq_t upper)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
mpq_set(var->upper, upper);
/* FREE -> LOWER
* LOWER -> LOWER
* UPPER -> BOXED/FIXED
* BOXED -> BOXED/FIXED
* FIXED -> BOXED/FIXED
*/
if (var->type == VAR_FREE)
var->type = VAR_UPPER;
else if (var->type != VAR_UPPER)
{
assert(var->type == VAR_LOWER || var->type == VAR_BOXED || var->type == VAR_FIXED);
var->type = mpq_equal(var->lower, var->upper) ? VAR_FIXED : VAR_BOXED;
}
}
void lps_setlhs(
Con* con,
const mpq_t lhs)
{
assert(con != NULL);
assert(con->sid == CON_SID);
mpq_set(con->lhs, lhs);
/* FREE -> LHS
* LHS -> LHS
* RHS -> RANGE/EQUAL
* RANGE -> RANGE/EQUAL
* EQUAL -> RANGE/EQUAL
*/
if (con->type == CON_FREE)
con->type = CON_LHS;
else if (con->type != CON_LHS)
{
assert(con->type == CON_RHS || con->type == CON_RANGE || con->type == CON_EQUAL);
con->type = mpq_equal(con->lhs, con->rhs) ? CON_EQUAL : CON_RANGE;
}
}
void lps_setrhs(
Con* con,
const mpq_t rhs)
{
assert(con != NULL);
assert(con->sid == CON_SID);
mpq_set(con->rhs, rhs);
/* FREE -> RHS
* RHS -> RHS
* LHS -> RANGE/EQUAL
* RANGE -> RANGE/EQUAL
* EQUAL -> RANGE/EQUAL
*/
if (con->type == CON_FREE)
con->type = CON_RHS;
else if (con->type != CON_RHS)
{
assert(con->type == CON_LHS || con->type == CON_RANGE || con->type == CON_EQUAL);
con->type = mpq_equal(con->lhs, con->rhs) ? CON_EQUAL : CON_RANGE;
}
}
void lps_setcontype( Con* con, ConType type)
{
assert(con != NULL);
assert(con->sid == CON_SID);
con->type = type;
}
ConType lps_contype(const Con* con)
{
assert(con != NULL);
assert(con->sid == CON_SID);
return con->type;
}
VarType lps_vartype(const Var* var)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
return var->type;
}
VarClass lps_getclass(const Var *var)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
return var->vclass;
}
void lps_setclass(Var *var, VarClass vclass)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
var->vclass = vclass;
}
void lps_getlhs(
const Con* con,
mpq_t lhs)
{
assert(con != NULL);
assert(con->sid == CON_SID);
mpq_set(lhs, con->lhs);
}
void lps_getrhs(
const Con* con,
mpq_t rhs)
{
assert(con != NULL);
assert(con->sid == CON_SID);
mpq_set(rhs, con->rhs);
}
const char* lps_varname(const Var* var)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
return var->name;
}
void lps_setvartype(
Var* var,
VarType type)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
var->type = type;
}
unsigned int lps_flags(const Con* con)
{
assert(con != NULL);
assert(con->sid == CON_SID);
return con->flags;
}
void lps_addflags(
Con* con,
unsigned int flags)
{
assert(con != NULL);
assert(con->sid == CON_SID);
con->flags |= flags;
}
void lps_setscale(
Con* con,
const mpq_t scale)
{
assert(con != NULL);
assert(con->sid == CON_SID);
mpq_set(con->scale, scale);
}
void lps_setpriority(
Var* var,
int priority)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
var->priority = priority;
}
void lps_setvalue(
Var* var,
const mpq_t value)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
mpq_set(var->value, value);
}
void lps_setstartval(
Var* var,
const mpq_t startval)
{
assert(var != NULL);
assert(var->sid == VAR_SID);
mpq_set(var->startval, startval);
}
void lps_setnamelen(
Lps* lp,
int name_len)
{
lp->name_len = name_len;
}
void lps_setindicator(
Con* con,
Var* var,
bool on_true)
{
assert(con != NULL);
assert(con->sid == CON_SID);
assert(var != NULL);
assert(var->sid == VAR_SID);
con->ind_var = var;
con->ind_dir = on_true;
}
void lps_stat(const Lps* lp)
{
assert(lps_valid(lp));
printf("Name: %s Variables: %d Constraints: %d Non Zeros: %d\n",
lp->name, lp->vars, lp->cons, lp->nonzeros);
}
int lps_getnamesize(const Lps* lp, LpFormat format)
{
int name_size = 0;
assert(lp != NULL);
switch(format)
{
case LP_FORM_LPF :
name_size = 1 + ((lp->name_len < MIN_NAME_LEN) ? LPF_NAME_LEN : lp->name_len);
break;
case LP_FORM_HUM :
name_size = 4096;
break;
case LP_FORM_MPS :
name_size = 1 + ((lp->name_len < MIN_NAME_LEN) ? MPS_NAME_LEN : lp->name_len);
break;
case LP_FORM_RLP :
name_size = 1 + ((lp->name_len < MIN_NAME_LEN) ? LPF_NAME_LEN : lp->name_len);
break;
case LP_FORM_PIP :
name_size = 1 + ((lp->name_len < MIN_NAME_LEN) ? PIP_NAME_LEN : lp->name_len);
break;
default :
abort();
}
assert(name_size > MIN_NAME_LEN);
return name_size;
}
void lps_write(
const Lps* lp,
FILE* fp,
LpFormat format,
const char* text)
{
assert(lp != NULL);
assert(fp != NULL);
lps_number(lp);
switch(format)
{
case LP_FORM_LPF :
case LP_FORM_RLP :
case LP_FORM_PIP :
case LP_FORM_HUM :
lpf_write(lp, fp, format, text);
break;
case LP_FORM_MPS :
mps_write(lp, fp, text);
break;
default :
abort();
}
}
static bool lpfstrncpy(char* t, const char* s, int len)
{
/* '@' was excluded, to make sure the appendix is unique.
*/
static const char* const allowed = "!#$%&()/,.;?_{}|~";
bool was_smashed = false;
while(--len >= 0 && *s != '\0')
{
if (isalnum(*s) || strchr(allowed, *s) != NULL)
*t = *s;
else
{
*t = '_';
was_smashed = true;
}
s++;
t++;
}
*t = '\0';
return was_smashed;
}
static void make_full_name(
char* target,
int size,
const char* name)
{
assert(target != NULL);
assert(size >= MIN_NAME_LEN);
assert(name != NULL);
const char* s = name;
bool first = true;
bool in_string = false;
int i = 0;
/* We allways start with a space
*/
while(*s != '\0' && size > i + 6)
{
if (*s != '#' && *s != '$')
target[i++] = *s;
else
{
if (first)
{
first = false;
target[i++] = '[';
}
else
{
if (in_string)
{
target[i++] = '\"';
in_string = false;
}
target[i++] = ',';
}
if (*s == '$')
{
assert(!in_string);
in_string = true;
target[i++] = '\"';
}
}
assert(size >= i);
s++;
}
if (size > i + 2)
{
if (in_string)
target[i++] = '\"';
if (!first)
target[i++] = ']';
}
target[i++] = '\0';
assert(size >= i);
}
/* size has to be big enough to store a '@', a '\0'
* and the var or row number.
*/
void lps_makename(
char* target,
int size,
const char* name,
int no)
{
char temp[9];
int len;
int nlen;
assert(target != NULL);
assert(size > MIN_NAME_LEN); /* 8+1, so we have at least '@' + 7 digits + '\0' */
assert(name != NULL);
assert(no >= -1);
assert(no <= 0xFFFFFFF); /* 7 hex digits = 268,435,455 */
nlen = (int)strlen(name);
/* There are 3 possibilities:
*
* i) name is smaller than size and does not contain problematic chars
* -> just copy it.
* ii) as above but contains unvalid chars
* -> copy it, transform the chars to '_' and append "@varnum".
* iii) the name is longer than the size.
* -> do as in ii) but only copy as much chars as fit.
* iv) no == -1
* -> generate a full human readable name
*/
if (no == -1)
make_full_name(target, size, name);
else if (nlen < size)
{
if (lpfstrncpy(target, name, nlen))
{
sprintf(temp, "@%x", (unsigned int)no);
len = size - (int)strlen(temp) - 1;
assert(len >= 0);
/* Trick: if len > strlen(target) it doesn't matter,
* lpfstrncmp always appends a '\0' and the strcat below
* will append temp at the right place.
* Otherwise it will be appended at len, which is the
* latest possible position.
*/
target[len] = '\0';
strcat(target, temp);
}
}
else
{
sprintf(temp, "@%x", (unsigned int)no);
len = size - (int)strlen(temp) - 1; /* -1 for '\0' */
assert(len >= 0);
(void)lpfstrncpy(target, name, len);
strcat(target, temp);
}
assert(strlen(target) <= (size_t)size - 1);
}
void lps_transtable(const Lps* lp, FILE* fp, LpFormat format, const char* head)
{
Var* var;
Con* con;
char* temp;
int namelen;
assert(lps_valid(lp));
assert(fp != NULL);
assert(head != NULL);
assert(format == LP_FORM_LPF || format == LP_FORM_MPS || format == LP_FORM_RLP || format == LP_FORM_PIP);
namelen = lps_getnamesize(lp, format);
temp = malloc((size_t)namelen);
assert(temp != NULL);
lps_number(lp);
for(var = lp->var_root; var != NULL; var = var->next)
{
lps_makename(temp, namelen, var->name, var->number);
if (var->type == VAR_FIXED)
fprintf(fp, "%s\tv %7d\t%-*s\t\"%s\"\t%.16e\n",
head, var->number, namelen - 1, temp, var->name, mpq_get_d(var->lower));
else
{
if (var->size > 0 || !mpq_equal(var->cost, const_zero))
fprintf(fp, "%s\tv %7d\t%-*s\t\"%s\"\n",
head, var->number, namelen - 1, temp, var->name);
}
}
for(con = lp->con_root; con != NULL; con = con->next)
{
lps_makename(temp, namelen, con->name, con->number);
fprintf(fp, "%s\tc %7d\t%-*s\t\"%s\"\t%.16e\n",
head, con->number, namelen - 1, temp, con->name, mpq_get_d(con->scale));
}
free(temp);
}
void lps_clearobj(const Lps* lp)
{
assert(lps_valid(lp));
for(Var* var = lp->var_root; var != NULL; var = var->next)
mpq_set(var->cost, const_zero);
}
void lps_scale(const Lps* lp)
{
Con* con;
Nzo* nzo;
mpq_t maxi;
mpq_t v;
assert(lps_valid(lp));
mpq_init(maxi);
mpq_init(v);
for(con = lp->con_root; con != NULL; con = con->next)
{
if ((con->flags & LP_FLAG_CON_SCALE) > 0)
{
mpq_set_ui(maxi, 0, 1); /* = 0 */
for(nzo = con->first; nzo != NULL; nzo = nzo->con_next)
{
mpq_abs(v, nzo->value);
if (mpq_cmp(v, maxi) > 0)
mpq_set(maxi, v);
}
mpq_inv(con->scale, maxi); /* scale = 1 / maxi */
if (HAS_RHS(con))
mpq_mul(con->rhs, con->rhs, con->scale);
if (HAS_LHS(con))
mpq_mul(con->lhs, con->lhs, con->scale);
for(nzo = con->first; nzo != NULL; nzo = nzo->con_next)
mpq_mul(nzo->value, nzo->value, con->scale);
}
}
mpq_clear(v);
mpq_clear(maxi);
}
bool lps_has_sos(const Lps* lp)
{
assert(lps_valid(lp));
return lp->soss > 0;
}
bool lps_con_sumup(const Con* con, mpq_t sum)
{
bool usable = true;
Nzo* nzo;
mpq_t val;
mpq_set_si(sum, 0, 1);
mpq_init(val);
for(nzo = con->first; nzo != NULL; nzo = nzo->con_next)
{
if (nzo->var->vclass != VAR_INT)
{
usable = false;
break;
}
mpq_mul(val, nzo->value, nzo->var->startval);
mpq_add(sum, sum, val);
}
mpq_clear(val);
return usable;
}
/* ------------------------------------------------------------------------- */
/* Emacs Local Variables: */
/* Emacs mode:c */
/* Emacs c-basic-offset:3 */
/* Emacs tab-width:8 */
/* Emacs indent-tabs-mode:nil */
/* Emacs End: */
/* ------------------------------------------------------------------------- */
zimpl-3.3.6/src/zimpl/blkmem.h 0000644 0014172 0006025 00000003261 13304236715 016125 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: blkmem.h */
/* Name....: Block Memory Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2007-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _BLKMEM_H_
#define _BLKMEM_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void blk_init(void);
extern void blk_exit(void);
extern void* blk_alloc(int size);
extern void blk_free(void* p, int size);
#ifdef __cplusplus
}
#endif
#endif /* _BLKMEM_H_ */
zimpl-3.3.6/src/zimpl/prog.h 0000644 0014172 0006025 00000005357 13304236715 015635 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: prog.h */
/* Name....: Program Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _PROG_H_
#define _PROG_H_
#ifndef _STMT_H_
#error "Need to include stmt.h before prog.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct program Prog;
/* prog.c
*/
extern void* prog_get_lp(void);
/*lint -sem( prog_new, 1p) */
extern Prog* prog_new(void);
/*lint -sem( prog_free, custodial(1), 1p == 1) */
extern void prog_free(Prog* prog);
/*lint -sem( prog_is_valid, 1p == 1) */
extern bool prog_is_valid(const Prog* prog);
/*lint -sem( prog_is_empty, 1p == 1) */
extern bool prog_is_empty(const Prog* prog);
/*lint -sem( prog_add_stmt, custodial(2), 1p == 1 && 2p == 1) */
extern void prog_add_stmt(Prog* prog, Stmt* stmt);
/*lint -sem( prog_print, 1p == 1 && 2p == 1) */
extern void prog_print(FILE* fp, const Prog* prog);
/*lint -sem( prog_execute, 1p == 1) */
extern void prog_execute(const Prog* prog, void* lp);
/*lint -sem( prog_tostr, 1p == 1 && nulterm(2), @p == 1) */
extern char* prog_tostr(const Prog* prog, const char* prefix, const char* title, size_t max_output_line_len);
/* load.c
*/
/*lint -sem( prog_load, nulterm(3), 1p == 1) */
extern void prog_load(Prog* prog, const char* cmd, const char* filename);
#ifdef __cplusplus
}
#endif
#endif /* _PROG_H_ */
zimpl-3.3.6/src/zimpl/setlist.c 0000644 0014172 0006025 00000030531 13304236715 016340 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: setlist.c */
/* Name....: Set List Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/hash.h"
#include "zimpl/list.h"
#include "zimpl/stmt.h"
#include "zimpl/set.h"
#include "zimpl/entry.h"
#include "zimpl/set4.h"
#ifdef _MSC_VER
#pragma warning (disable: 4100) /* unreferenced formal parameter */
#endif
#define SET_LIST_SID 0x5345544c
#define SET_LIST_ITER_SID 0x53454c49
#define HASH_THRESHOLD 12
/* -------------------------------------------------------------------------
* --- valid
* -------------------------------------------------------------------------
*/
static bool set_list_is_valid(const Set* set)
{
if (set == NULL
|| !SID_ok2(set->list, SET_LIST_SID)
|| set->head.refc <= 0
|| set->head.dim != 1
|| set->head.members < 0
|| set->list.size < set->head.members
|| set->list.member == NULL)
return false;
for(SetIterIdx i = 0; i < set->head.members; i++)
if (!elem_is_valid(set->list.member[i]))
return false;
return true;
}
static bool set_list_iter_is_valid(const SetIter*iter)
{
return iter != NULL
&& SID_ok2(iter->list, SET_LIST_ITER_SID)
&& iter->list.first >= 0
&& iter->list.last >= -1
&& iter->list.now >= 0
&& iter->list.now >= iter->list.first;
}
/* -------------------------------------------------------------------------
* --- internal
* -------------------------------------------------------------------------
*/
/* Return index number of element. -1 if not present
*/
static SetIterIdx lookup_elem_idx(const Set* set, const Elem* elem)
{
assert(set_list_is_valid(set));
assert(elem_is_valid(elem));
if (set->list.hash != NULL)
return hash_lookup_elem_idx(set->list.hash, elem);
for(SetIterIdx i = 0; i < set->list.head.members; i++)
if (!elem_cmp(elem, set->list.member[i]))
return i;
return -1;
}
/* -------------------------------------------------------------------------
* --- new
* -------------------------------------------------------------------------
*/
Set* set_list_new(int size, int flags)
{
Set* set;
assert(size > 0);
set = calloc(1, sizeof(*set));
assert(set != NULL);
set->head.refc = 1;
set->head.dim = 1;
set->head.members = 0;
set->head.type = SET_LIST;
set->list.size = size;
set->list.member = calloc((size_t)size, sizeof(*set->list.member));
assert(set->list.member != NULL);
if ((flags & SET_NO_HASH) == 0 && size > HASH_THRESHOLD)
set->list.hash = hash_new(HASH_ELEM_IDX, size);
SID_set2(set->list, SET_LIST_SID);
assert(set_list_is_valid(set));
return set;
}
SetIterIdx set_list_add_elem(Set* set, const Elem* elem, SetCheckType check)
{
SetIterIdx idx = -1;
assert(set_list_is_valid(set));
assert(elem_is_valid(elem));
if (check != SET_CHECK_NONE && (idx = lookup_elem_idx(set, elem)) >= 0)
{
if (check != SET_CHECK_QUIET)
{
assert(check == SET_CHECK_WARN);
if (stmt_trigger_warning(164))
{
fprintf(stderr, "--- Warning 164: Duplicate element ");
elem_print(stderr, elem, true);
fprintf(stderr, " for set rejected\n");
}
}
}
else
{
idx = set->head.members;
set->list.member[idx] = elem_copy(elem);
if (set->list.hash != NULL)
hash_add_elem_idx(set->list.hash, set->list.member[idx], idx);
set->head.members++;
assert(set->head.members <= set->list.size);
}
assert(idx >= 0);
return idx;
}
Set* set_list_new_from_elems(const List* list, SetCheckType check)
{
ListElem* le = NULL;
Set* set;
int n;
assert(list_is_valid(list));
n = list_get_elems(list);
assert(n > 0);
set = set_list_new(n, SET_DEFAULT);
while(n-- > 0)
(void)set_list_add_elem(set, list_get_elem(list, &le), check);
assert(set_list_is_valid(set));
return set;
}
Set* set_list_new_from_tuples(const List* list, SetCheckType check)
{
ListElem* le = NULL;
const Tuple* tuple;
Set* set;
int n;
assert(list_is_valid(list));
n = list_get_elems(list);
assert(n > 0);
set = set_list_new(n, SET_DEFAULT);
while(n-- > 0)
{
tuple = list_get_tuple(list, &le);
assert(tuple_get_dim(tuple) == 1);
(void)set_list_add_elem(set, tuple_get_elem(tuple, 0), check);
}
assert(set_list_is_valid(set));
return set;
}
Set* set_list_new_from_entries(const List* list, SetCheckType check)
{
ListElem* le = NULL;
const Tuple* tuple;
Set* set;
int n;
assert(list_is_valid(list));
n = list_get_elems(list);
assert(n > 0);
set = set_list_new(n, SET_DEFAULT);
while(n-- > 0)
{
tuple = entry_get_tuple(list_get_entry(list, &le));
assert(tuple_get_dim(tuple) == 1);
(void)set_list_add_elem(set, tuple_get_elem(tuple, 0), check);
}
assert(set_list_is_valid(set));
return set;
}
/* -------------------------------------------------------------------------
* --- copy
* -------------------------------------------------------------------------
*/
static Set* set_list_copy(const Set* source)
{
Set* set = (Set*)source;
set->head.refc++;
return set;
}
/* -------------------------------------------------------------------------
* --- free
* -------------------------------------------------------------------------
*/
static void set_list_free(Set* set)
{
assert(set_list_is_valid(set));
set->head.refc--;
if (set->head.refc == 0)
{
int i;
SID_del2(set->list);
for(i = 0; i < set->head.members; i++)
elem_free(set->list.member[i]);
if (set->list.hash != NULL)
hash_free(set->list.hash);
free(set->list.member);
free(set);
}
}
/* -------------------------------------------------------------------------
* --- lookup
* -------------------------------------------------------------------------
*/
/* Return index number of element. -1 if not present
*/
static SetIterIdx set_list_lookup_idx(const Set* set, const Tuple* tuple, int offset)
{
assert(set_list_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset < tuple_get_dim(tuple));
return lookup_elem_idx(set, tuple_get_elem(tuple, offset));
}
/* -------------------------------------------------------------------------
* --- get_tuple
* -------------------------------------------------------------------------
*/
static void set_list_get_tuple(
const Set* set,
SetIterIdx idx,
Tuple* tuple,
int offset)
{
assert(set_list_is_valid(set));
assert(idx >= 0);
assert(idx <= set->head.members);
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset < tuple_get_dim(tuple));
tuple_set_elem(tuple, offset, elem_copy(set->list.member[idx]));
}
/* -------------------------------------------------------------------------
* --- iter_init
* -------------------------------------------------------------------------
*/
/* Initialise Iterator. Write into iter
*/
static SetIter* set_list_iter_init(
const Set* set,
const Tuple* pattern,
int offset)
{
const Elem* elem;
SetIter* iter;
assert(set_list_is_valid(set));
assert(pattern == NULL || tuple_is_valid(pattern));
assert(offset >= 0);
assert(pattern == NULL || offset < tuple_get_dim(pattern));
iter = calloc(1, sizeof(*iter));
assert(iter != NULL);
if (pattern == NULL)
{
iter->list.first = 0;
iter->list.last = set->head.members - 1;
}
else
{
elem = tuple_get_elem(pattern, offset);
if (elem_get_type(elem) == ELEM_NAME)
{
iter->list.first = 0;
iter->list.last = set->head.members - 1;
}
else
{
iter->list.first = lookup_elem_idx(set, elem);
if (iter->list.first >= 0)
iter->list.last = iter->list.first;
else
{
iter->list.first = 1;
iter->list.last = 0;
}
}
}
iter->list.now = iter->list.first;
SID_set2(iter->list, SET_LIST_ITER_SID);
assert(set_list_iter_is_valid(iter));
return iter;
}
/* -------------------------------------------------------------------------
* --- iter_next
* -------------------------------------------------------------------------
*/
/* false means, there is no further element
*/
static bool set_list_iter_next(
SetIter* iter,
const Set* set,
Tuple* tuple,
int offset)
{
assert(set_list_iter_is_valid(iter));
assert(set_list_is_valid(set));
assert(tuple_is_valid(tuple));
assert(offset >= 0);
assert(offset < tuple_get_dim(tuple));
if (iter->list.now > iter->list.last)
return false;
tuple_set_elem(tuple, offset, elem_copy(set->list.member[iter->list.now]));
iter->list.now++;
return true;
}
/* -------------------------------------------------------------------------
* --- iter_exit
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_list_iter_exit(SetIter* iter, UNUSED const Set* set)
{
assert(set_list_iter_is_valid(iter));
SID_del2(iter->list);
free(iter);
}
/* -------------------------------------------------------------------------
* --- iter_reset
* -------------------------------------------------------------------------
*/
/*ARGSUSED*/
static void set_list_iter_reset(SetIter* iter, UNUSED const Set* set)
{
assert(set_list_iter_is_valid(iter));
iter->list.now = iter->list.first;
}
/* -------------------------------------------------------------------------
* --- vtab_init
* -------------------------------------------------------------------------
*/
void set_list_init(SetVTab* vtab)
{
vtab[SET_LIST].set_copy = set_list_copy;
vtab[SET_LIST].set_free = set_list_free;
vtab[SET_LIST].set_lookup_idx = set_list_lookup_idx;
vtab[SET_LIST].set_get_tuple = set_list_get_tuple;
vtab[SET_LIST].iter_init = set_list_iter_init;
vtab[SET_LIST].iter_next = set_list_iter_next;
vtab[SET_LIST].iter_exit = set_list_iter_exit;
vtab[SET_LIST].iter_reset = set_list_iter_reset;
vtab[SET_LIST].set_is_valid = set_list_is_valid;
}
/* -------------------------------------------------------------------------
* --- extras
* -------------------------------------------------------------------------
*/
const Elem* set_list_get_elem(const Set* set, SetIterIdx idx)
{
assert(set_list_is_valid(set));
assert(idx >= 0);
assert(idx < set->head.members);
return set->list.member[idx];
}
zimpl-3.3.6/src/zimpl/ratordwrite.c 0000644 0014172 0006025 00000005610 13304236715 017217 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: ratordwrite.c */
/* Name....: ORD File Write */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include "zimpl/mshell.h"
#include
#include "zimpl/gmpmisc.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/bound.h"
#include "zimpl/mme.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/ratlp.h"
#include "zimpl/ratlpstore.h"
/* A specification for the ORD file format can be found in the
* ILOG CPLEX 7.0 Reference Manual page 545.
*/
void lps_orderfile(
const Lps* lp,
FILE* fp,
LpFormat format,
const char* text)
{
const Var* var;
int name_size;
char* vtmp;
assert(lp != NULL);
assert(fp != NULL);
assert(format == LP_FORM_LPF || format == LP_FORM_MPS);
name_size = lps_getnamesize(lp, format);
vtmp = malloc((size_t)name_size);
assert(vtmp != NULL);
if (text != NULL)
fprintf(fp, "* %s\n", text);
fprintf(fp, "NAME %8.8s\n", lp->name);
for(var = lp->var_root; var != NULL; var = var->next)
{
if (var->vclass == VAR_CON)
continue;
if (var->size == 0)
continue;
if (var->type == VAR_FIXED)
continue;
lps_makename(vtmp, name_size, var->name, var->number);
fprintf(fp, " %-*s %8d %.10e\n",
name_size - 1, vtmp, var->priority, mpq_get_d(var->startval));
}
fprintf(fp, "ENDATA\n");
free(vtmp);
}
zimpl-3.3.6/src/zimpl/elem.c 0000644 0014172 0006025 00000017675 13304236715 015611 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: elem.c */
/* Name....: Element Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include "zimpl/lint.h"
#include
#include "zimpl/mshell.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/mme.h"
#include "zimpl/strstore.h"
#define ELEM_STORE_SIZE 1000
#define ELEM_SID 0x456c656d
typedef union element_value ElemValue;
typedef struct element_storage ElemStore;
union element_value
{
Numb* numb;
const char* strg;
const char* name;
Elem* next;
};
struct element
{
SID
ElemType type;
ElemValue value;
};
struct element_storage
{
Elem* begin;
ElemStore* next;
};
static ElemStore* store_anchor = NULL;
static Elem* store_free = NULL;
static int store_count = 0;
static void extend_storage(void)
{
ElemStore* store = calloc(1, sizeof(*store));
Elem* elem;
int i;
assert(store != NULL);
store->begin = malloc(ELEM_STORE_SIZE * sizeof(*store->begin));
store->next = store_anchor;
store_anchor = store;
for(i = 0; i < ELEM_STORE_SIZE - 1; i++)
{
elem = &store->begin[i];
elem->type = ELEM_FREE;
elem->value.next = &store->begin[i + 1];
SID_set(elem, ELEM_SID);
assert(elem_is_valid(elem));
}
elem = &store->begin[i];
elem->type = ELEM_FREE;
elem->value.next = store_free;
SID_set(elem, ELEM_SID);
assert(elem_is_valid(elem));
store_free = &store->begin[0];
assert(store->begin != NULL);
assert(store_anchor != NULL);
assert(store_free != NULL);
}
static Elem* new_elem(void)
{
Elem* elem;
if (store_free == NULL)
extend_storage();
assert(store_free != NULL);
elem = store_free;
store_free = elem->value.next;
store_count++;
assert(elem->type == ELEM_FREE);
assert(elem_is_valid(elem));
return elem;
}
void elem_init()
{
}
void elem_exit()
{
ElemStore* store;
ElemStore* next;
if (store_count != 0)
printf("Elem store count %d\n", store_count);
for(store = store_anchor; store != NULL; store = next)
{
#if 0 /* only for debugging */
int i;
for(i = 0; i < ELEM_STORE_SIZE - 1; i++)
{
elem_print(stderr, &store->begin[i], true);
fprintf(stderr, "\n");
}
#endif
next = store->next;
free(store->begin);
free(store);
}
store_anchor = NULL;
store_free = NULL;
store_count = 0;
}
Elem* elem_new_numb(const Numb* numb)
{
Elem* elem = new_elem();
assert(elem != NULL);
elem->type = ELEM_NUMB;
elem->value.numb = numb_copy(numb);
return elem;
}
Elem* elem_new_strg(const char* strg)
{
Elem* elem = new_elem();
assert(strg != NULL);
assert(elem != NULL);
elem->type = ELEM_STRG;
elem->value.strg = strg;
return elem;
}
Elem* elem_new_name(const char* name)
{
Elem* elem = new_elem();
assert(name != NULL);
assert(elem != NULL);
elem->type = ELEM_NAME;
elem->value.strg = name;
return elem;
}
void elem_free(Elem* elem)
{
assert(elem_is_valid(elem));
if (elem->type == ELEM_NUMB)
numb_free(elem->value.numb);
elem->type = ELEM_FREE;
elem->value.next = store_free;
store_free = elem;
store_count--;
}
bool elem_is_valid(const Elem* elem)
{
return elem != NULL && SID_ok(elem, ELEM_SID);
}
Elem* elem_copy(const Elem* source)
{
Elem* elem = new_elem();
assert(elem_is_valid(source));
assert(elem_is_valid(elem));
if (source->type != ELEM_NUMB)
*elem = *source;
else
{
elem->type = ELEM_NUMB;
elem->value.numb = numb_copy(source->value.numb);
}
return elem;
}
/* 0 wenn gleich, sonst != 0
*/
bool elem_cmp(const Elem* elem_a, const Elem* elem_b)
{
assert(elem_is_valid(elem_a));
assert(elem_is_valid(elem_b));
assert(elem_a->type != ELEM_ERR);
assert(elem_b->type != ELEM_ERR);
/* Auf die schnelle vorweg.
*/
if (elem_a == elem_b)
return false;
if (elem_a->type != elem_b->type)
{
fprintf(stderr,
"*** Error 160: Comparison of elements with different types ");
elem_print(stderr, elem_a, true);
fprintf(stderr, " / ");
elem_print(stderr, elem_b, true);
fputc('\n', stderr);
zpl_exit(EXIT_FAILURE);
}
assert(elem_a->type == elem_b->type);
if (elem_a->type == ELEM_STRG)
return strcmp(elem_a->value.strg, elem_b->value.strg) != 0;
assert(elem_a->type == ELEM_NUMB);
return !numb_equal(elem_a->value.numb, elem_b->value.numb);
}
ElemType elem_get_type(const Elem* elem)
{
assert(elem_is_valid(elem));
return elem->type;
}
const Numb* elem_get_numb(const Elem* elem)
{
assert(elem_is_valid(elem));
assert(elem->type == ELEM_NUMB);
return elem->value.numb;
}
const char* elem_get_strg(const Elem* elem)
{
assert(elem_is_valid(elem));
assert(elem->type == ELEM_STRG);
assert(elem->value.strg != NULL);
return elem->value.strg;
}
const char* elem_get_name(const Elem* elem)
{
assert(elem_is_valid(elem));
assert(elem->type == ELEM_NAME);
assert(elem->value.name != NULL);
return elem->value.name;
}
void elem_print(FILE* fp, const Elem* elem, bool use_quotes)
{
assert(elem_is_valid(elem));
switch(elem->type)
{
case ELEM_NUMB :
fprintf(fp, "%.16g", numb_todbl(elem->value.numb));
break;
case ELEM_STRG :
fprintf(fp, use_quotes ? "\"%s\"" : "%s", elem->value.strg);
break;
case ELEM_NAME :
fprintf(fp, "%s", elem->value.name);
break;
case ELEM_FREE :
fprintf(fp, "Unused Elem!");
break;
default :
abort();
}
}
unsigned int elem_hash(const Elem* elem)
{
unsigned int hcode = 0;
switch(elem->type)
{
case ELEM_NUMB :
hcode = numb_hash(elem->value.numb);
break;
case ELEM_STRG :
hcode = str_hash(elem->value.strg);
break;
case ELEM_NAME :
hcode = str_hash(elem->value.name);
break;
case ELEM_FREE :
default :
abort();
}
return hcode;
}
char* elem_tostr(const Elem* elem)
{
char* str;
assert(elem_is_valid(elem));
switch(elem->type)
{
case ELEM_NUMB :
str = malloc(32);
assert(str != NULL);
sprintf(str, "%.16g", numb_todbl(elem->value.numb));
break;
case ELEM_STRG :
str = strdup(elem->value.strg);
break;
case ELEM_NAME :
str = strdup(elem->value.name);
break;
case ELEM_FREE :
default :
abort();
}
assert(str != NULL);
return str;
}
zimpl-3.3.6/src/zimpl/random.h 0000644 0014172 0006025 00000003351 13304236715 016136 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: random.h */
/* Name....: Random Number Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2007-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _RANDOM_H_
#define _RANDOM_H_
#ifdef __cplusplus
extern "C" {
#endif
extern void rand_init(unsigned long s);
extern unsigned int rand_get_int32(void);
/*lint -sem( rand_get_range, 1n < 2n) */
extern int rand_get_range(int mini, int maxi);
#ifdef __cplusplus
}
#endif
#endif /* RANDOM */
zimpl-3.3.6/src/zimpl/ratpresolve.c 0000644 0014172 0006025 00000037560 13304236715 017230 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: lpstore.c */
/* Name....: Store Linear Programm */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2003-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if 0 /* Not used anymore ??? */
#include
#include
#include
#include
#include
#include
#include "zimpl/lint.h"
#include "zimpl/mshell.h"
#include
#include "zimpl/gmpmisc.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/bound.h"
#include "zimpl/mme.h"
#include "zimpl/mono.h"
#include "zimpl/term.h"
#include "zimpl/ratlp.h"
#include "zimpl/ratlpstore.h"
/*lint -e{818} supress "Pointer parameter 'var' could be declared as pointing to const" */
static void remove_fixed_var(
Lps* lp,
Var* var,
int verbose_level)
{
Nzo* nzo;
mpq_t x;
mpq_t temp;
bool is_zero;
assert(lp != NULL);
assert(var != NULL);
assert(var->type == VAR_FIXED && mpq_equal(var->lower, var->upper));
if (verbose_level > 0)
printf("Removing variable %s fixed to %g\n", var->name, mpq_get_d(var->lower));
mpq_init(x);
mpq_init(temp);
is_zero = mpq_equal(var->lower, x /* zero */);
while(var->first != NULL)
{
nzo = var->first;
/* Do we have to ajust the lhs/rhs ?
*/
if (!is_zero)
{
mpq_mul(x, var->lower, nzo->value);
/* do we have a valid rhs ?
*/
if (HAS_RHS(nzo->con))
{
mpq_sub(temp, nzo->con->rhs, x);
lps_setrhs(nzo->con, temp);
}
/* do we have a valid lhs ?
*/
if (HAS_LHS(nzo->con))
{
mpq_sub(temp, nzo->con->lhs, x);
lps_setlhs(nzo->con, temp);
}
}
lps_delnzo(lp, nzo);
}
mpq_clear(temp);
mpq_clear(x);
}
static PSResult simple_rows(
Lps* lp,
Bool* again,
int verbose_level)
{
bool have_up;
bool have_lo;
mpq_t up;
mpq_t lo;
Nzo* nzo;
Var* var;
Con* con;
Con* con_next;
int rem_rows = 0;
int rem_nzos = 0;
mpq_init(up);
mpq_init(lo);
for(con = lp->con_root; con != NULL; con = con_next)
{
con_next = con->next;
/* infeasible range row
*/
if (con->type == CON_RANGE && mpq_cmp(con->lhs, con->rhs) > 0)
{
printf("Infeasible range row %s lhs=%g rhs=%g\n",
con->name, mpq_get_d(con->lhs), mpq_get_d(con->rhs));
return PRESOLVE_INFEASIBLE;
}
/* empty row ?
*/
if (con->size == 0)
{
if ( (HAS_RHS(con) && mpq_cmp(con->rhs, const_zero) < 0)
|| (HAS_LHS(con) && mpq_cmp(con->lhs, const_zero) > 0))
{
printf("Infeasible empty row %s lhs=%g rhs=%g\n",
con->name, mpq_get_d(con->lhs), mpq_get_d(con->rhs));
return PRESOLVE_INFEASIBLE;
}
if (verbose_level > 0)
printf("Empty row %s removed\n", con->name);
lps_delcon(lp, con);
rem_rows++;
continue;
}
/* unconstraint constraint
*/
if (con->type == CON_FREE)
{
if (verbose_level > 0)
printf("Unconstraint row %s removed\n", con->name);
rem_rows++;
rem_nzos += con->size;
lps_delcon(lp, con);
continue;
}
/* row singleton
*/
if (con->size == 1)
{
have_up = false;
have_lo = false;
nzo = con->first;
var = nzo->var;
if (mpq_cmp(nzo->value, const_zero) > 0) /* x > 0 */
{
if (HAS_RHS(con))
{
mpq_div(up, con->rhs, nzo->value);
have_up = true;
}
if (HAS_LHS(con))
{
mpq_div(lo, con->lhs, nzo->value);
have_lo = true;
}
}
else if (mpq_cmp(nzo->value, const_zero) < 0) /* x < 0 */
{
if (HAS_RHS(con))
{
mpq_div(lo, con->rhs, nzo->value);
have_lo = true;
}
if (HAS_LHS(con))
{
mpq_div(up, con->lhs, nzo->value);
have_up = true;
}
}
else if ((HAS_RHS(con) && !mpq_equal(con->rhs, const_zero))
|| (HAS_LHS(con) && !mpq_equal(con->lhs, const_zero)))
{
/* x == 0 rhs/lhs != 0 */
printf("Infeasibel row %s Zero row singleton with non zero lhs or rhs\n",
con->name);
return PRESOLVE_INFEASIBLE;
}
assert(!HAS_LOWER(var) || !HAS_UPPER(var) || mpq_cmp(var->lower, var->upper) <= 0);
if (have_up && (!HAS_UPPER(var) || mpq_cmp(up, var->upper) < 0))
lps_setupper(var, up);
if (have_lo && (!HAS_LOWER(var) || mpq_cmp(lo, var->lower) > 0))
lps_setlower(var, lo);
if (HAS_LOWER(var) && HAS_UPPER(var) && mpq_cmp(var->lower, var->upper) > 0)
{
printf("Row %s implise infeasible bounds on var %s, lower=%g upper=%g\n",
con->name, var->name, mpq_get_d(var->lower), mpq_get_d(var->upper));
return PRESOLVE_INFEASIBLE;
}
if (verbose_level > 1)
printf("Row %s singleton var %s set to lower=%g upper=%g\n",
con->name, var->name, mpq_get_d(var->lower), mpq_get_d(var->upper));
rem_rows++;
rem_nzos++;
lps_delcon(lp, con);
continue;
}
}
assert(rem_rows != 0 || rem_nzos == 0);
if (rem_rows > 0)
{
*again = true;
if (verbose_level > 0)
printf("Simple row presolve removed %d rows and %d non-zeros\n",
rem_rows, rem_nzos);
}
mpq_clear(up);
mpq_clear(lo);
return PRESOLVE_OKAY;
}
static PSResult handle_col_singleton(
Lps* lp,
Var* var,
int verbose_level,
int* rem_cols,
int* rem_nzos)
{
Nzo* nzo;
Con* con;
int cmpres;
mpq_t maxobj;
assert(lp != NULL);
assert(var != NULL);
assert(verbose_level >= 0);
assert(rem_cols != NULL);
assert(rem_nzos != NULL);
nzo = var->first;
con = nzo->con;
assert(!mpq_equal(nzo->value, const_zero));
mpq_init(maxobj);
mpq_set(maxobj, var->cost);
if (lp->direct == LP_MIN)
mpq_neg(maxobj, maxobj);
/* Value is positive
*/
if (mpq_cmp(nzo->value, const_zero) > 0.0)
{
/* max -3 x
* s.t. 5 x (<= 8)
* l <= x
*
* and we have NO lhs, (rhs does not matter)
*/
if (!HAS_LHS(con))
{
cmpres = mpq_cmp(maxobj, const_zero);
/* The objective is either zero or negative
*/
if (cmpres <= 0)
{
/* If we have no lower bound
*/
if (!HAS_LOWER(var))
{
/* ... but a negative objective, so we get unbounded
*/
if (cmpres < 0)
{
printf("Unbounded var %s\n", var->name);
return PRESOLVE_UNBOUNDED;
}
/* With a zero objective and no bounds, there is not
* much we can do.
*/
}
else
{
/* now we know we want to go to the lower bound.
*/
lps_setupper(var, var->lower);
remove_fixed_var(lp, var, verbose_level);
(*rem_cols)++;
(*rem_nzos)++;
return PRESOLVE_OKAY;
}
}
}
/* max 3 x
* s.t. 5 x (>= 8)
* x <= u
*
* and we have NO rhs, (lhs does not matter)
*/
if (!HAS_RHS(con))
{
cmpres = mpq_cmp(maxobj, const_zero);
/* The objective is either zero or positive
*/
if (cmpres >= 0)
{
/* If we have no upper bound
*/
if (!HAS_UPPER(var))
{
/* ... but a positive objective, so we get unbounded
*/
if (cmpres > 0)
{
printf("Unbounded var %s\n", var->name);
return PRESOLVE_UNBOUNDED;
}
/* With a zero objective and no bounds, there is not
* much we can do.
*/
}
else
{
/* now we know we want to go to the upper bound.
*/
lps_setlower(var, var->upper);
remove_fixed_var(lp, var, verbose_level);
(*rem_cols)++;
(*rem_nzos)++;
return PRESOLVE_OKAY;
}
}
}
}
else
{
/* Value is negative
*/
assert(mpq_cmp(nzo->value, const_zero) < 0.0);
/* max -3 x
* s.t. -5 x (>= 8)
* l <= x
*/
if (!HAS_RHS(con))
{
cmpres = mpq_cmp(maxobj, const_zero);
if (cmpres <= 0)
{
if (!HAS_LOWER(var))
{
if (cmpres < 0)
{
printf("Unbounded var %s\n", var->name);
return PRESOLVE_UNBOUNDED;
}
}
else
{
lps_setupper(var, var->lower);
remove_fixed_var(lp, var, verbose_level);
(*rem_cols)++;
(*rem_nzos)++;
return PRESOLVE_OKAY;
}
}
}
/* max 3 x
* s.t. -5 x (<= 8)
* x <= u
*/
if (!HAS_LHS(con))
{
cmpres = mpq_cmp(maxobj, const_zero);
if (cmpres >= 0)
{
if (!HAS_UPPER(var))
{
if (cmpres > 0)
{
printf("Unbounded var %s\n", var->name);
return PRESOLVE_UNBOUNDED;
}
}
else
{
lps_setlower(var, var->upper);
remove_fixed_var(lp, var, verbose_level);
(*rem_cols)++;
(*rem_nzos)++;
return PRESOLVE_OKAY;
}
}
}
}
mpq_clear(maxobj);
return PRESOLVE_OKAY;
}
static PSResult simple_cols(
Lps* lp,
Bool* again,
int verbose_level)
{
PSResult res;
mpq_t maxobj;
int rem_cols = 0;
int rem_nzos = 0;
Var* var;
mpq_init(maxobj);
for(var = lp->var_root; var != NULL; var = var->next)
{
if (var->type == VAR_FIXED && var->size == 0)
continue;
/* Empty column ?
*/
if (var->size == 0)
{
mpq_set(maxobj, var->cost);
if (lp->direct == LP_MIN)
mpq_neg(maxobj, maxobj);
if (mpq_cmp(maxobj, const_zero) > 0)
{
/* Do we not have an upper bound ?
*/
if (!HAS_UPPER(var))
{
printf("Var %s unbounded\n", var->name);
return PRESOLVE_UNBOUNDED;
}
lps_setlower(var, var->upper);
}
else if (mpq_cmp(maxobj, const_zero) < 0)
{
/* Do we not have an lower bound ?
*/
if (!HAS_LOWER(var))
{
printf("Var %s unbounded\n", var->name);
return PRESOLVE_UNBOUNDED;
}
lps_setupper(var, var->lower);
}
else
{
assert(mpq_equal(maxobj, const_zero));
/* any value within the bounds is ok
*/
if (HAS_LOWER(var))
lps_setupper(var, var->lower);
else if (HAS_UPPER(var))
lps_setlower(var, var->upper);
else
{
lps_setlower(var, const_zero);
lps_setupper(var, const_zero);
}
}
if (verbose_level > 1)
printf("Empty var %s fixed\n", var->name);
rem_cols++;
continue;
}
/* infeasible bounds ?
*/
if (var->type == VAR_BOXED && mpq_cmp(var->lower, var->upper) > 0)
{
printf("Var %s infeasible bounds lower=%g upper=%g\n",
var->name, mpq_get_d(var->lower), mpq_get_d(var->upper));
return PRESOLVE_INFEASIBLE;
}
/* Fixed column ?
*/
if (var->type == VAR_FIXED)
{
assert(var->size > 0);
rem_cols++;
rem_nzos += var->size;
remove_fixed_var(lp, var, verbose_level);
continue;
}
/* Column singleton
*/
if (var->size == 1)
{
res = handle_col_singleton(lp, var, verbose_level, &rem_cols, &rem_nzos);
if (res != PRESOLVE_OKAY)
return res;
}
}
assert(rem_cols != 0 || rem_nzos == 0);
if (rem_cols > 0)
{
*again = true;
if (verbose_level > 0)
printf("Simple col presolve removed %d cols and %d non-zeros\n",
rem_cols, rem_nzos);
}
mpq_clear(maxobj);
return PRESOLVE_OKAY;
}
PSResult lps_presolve(Lps* lp, int verbose_level)
{
PSResult ret = PRESOLVE_OKAY;
bool again;
/*
bool rcagain;
bool rragain;
*/
do
{
again = false;
if (ret == PRESOLVE_OKAY)
ret = simple_rows(lp, &again, verbose_level);
if (ret == PRESOLVE_OKAY)
ret = simple_cols(lp, &again, verbose_level);
assert(ret == PRESOLVE_OKAY || again == false);
}
while(again);
#if 0
if (ret == OKAY)
ret = redundantCols(lp, rcagain);
if (ret == OKAY)
ret = redundantRows(lp, rragain);
again = (ret == OKAY) && (rcagain || rragain);
/* This has to be a loop, otherwise we could end up with
* empty rows.
*/
while(again)
{
again = false;
if (ret == OKAY)
ret = simpleRows(lp, again);
if (ret == OKAY)
ret = simpleCols(lp, again);
assert(ret == OKAY || again == false);
}
VERBOSE1({ std::cout << "IREDSM25 redundant simplifier removed "
<< m_remRows << " rows, "
<< m_remNzos << " nzos, changed "
<< m_chgBnds << " col bounds "
<< m_chgLRhs << " row bounds,"
<< std::endl; });
#endif
/* ??? does not work, because vars are not deleted */
if (lp->vars == 0 || lp->cons == 0)
{
/* ??? Check if this is ok.
*/
assert(lp->vars == 0 && lp->cons == 0);
printf("Simplifier removed all variables and constraints\n");
ret = PRESOLVE_VANISHED;
}
return ret;
}
#endif
zimpl-3.3.6/src/zimpl/mono.c 0000644 0014172 0006025 00000023300 13304236715 015615 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: mono.c */
/* Name....: Monom Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2007-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
/* #define TRACE 1 */
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/entry.h"
#include "zimpl/mono.h"
#define MONO_SID 0x4d6f6e6f
#define MOEL_SID 0x4d6f456c
Mono* mono_new(const Numb* coeff, const Entry* entry, MFun fun)
{
Mono* mono = calloc(1, sizeof(*mono));
Trace("mono_new");
assert(mono != NULL);
assert(entry_is_valid(entry));
assert(entry_get_type(entry) == SYM_VAR);
mono->count = 1;
mono->coeff = numb_copy(coeff);
mono->fun = fun;
mono->first.entry = entry_copy(entry);
mono->first.next = NULL;
SID_set(mono, MONO_SID);
SID_set2(mono->first, MOEL_SID);
assert(mono_is_valid(mono));
return mono;
}
#ifndef NDEBUG
bool mono_is_valid(const Mono* mono)
{
const MonoElem* e;
int count = 1;
if (mono == NULL
|| !SID_ok(mono, MONO_SID)
|| !SID_ok2(mono->first, MOEL_SID)
|| mono->count < 1)
abort();
mem_check(mono);
assert(entry_is_valid(mono->first.entry));
for(e = mono->first.next; e != NULL; e = e->next)
{
count++;
mem_check(e);
if (!SID_ok(e, MOEL_SID))
abort();
assert(entry_is_valid(e->entry));
assert(entry_get_type(e->entry) == SYM_VAR);
}
if (count != mono->count)
abort();
return true;
}
#endif
void mono_free(Mono* mono)
{
MonoElem* e;
MonoElem* q;
Trace("mono_free");
assert(mono_is_valid(mono));
for(e = mono->first.next; e != NULL; e = q)
{
q = e->next;
entry_free(e->entry);
SID_del(e);
free(e);
}
entry_free(mono->first.entry);
numb_free(mono->coeff);
SID_del2(mono->first);
SID_del(mono);
free(mono);
}
void mono_mul_entry(
Mono* mono,
const Entry* entry)
{
MonoElem* e;
Var* var;
MonoElem* last;
Trace("mono_add_elem");
assert(mono_is_valid(mono));
assert(entry_is_valid(entry));
assert(entry_get_type(entry) == SYM_VAR);
var = entry_get_var(entry);
/* ??? This ensures that if the same variable is to come several times,
* all of them come together, i.e. yxy is not allowed, yyx would be ok.
* Is there any reason to do this?
*/
for(e = &mono->first; e != NULL; e = e->next)
{
last = e;
assert(entry_is_valid(e->entry));
if (var == entry_get_var(e->entry))
break;
}
assert(last != NULL);
e = calloc(1, sizeof(*e));
e->entry = entry_copy(entry);
e->next = last->next;
SID_set(e, MOEL_SID);
last->next = e;
mono->count++;
assert(mono_is_valid(mono));
}
Mono* mono_copy(const Mono* mono)
{
Mono* mnew;
MonoElem* e;
assert(mono_is_valid(mono));
mnew = mono_new(mono->coeff, mono->first.entry, mono->fun);
for(e = mono->first.next; e != NULL; e = e->next)
mono_mul_entry(mnew, e->entry);
assert(mono_is_valid(mnew));
return mnew;
}
void mono_mul_coeff(const Mono* mono, const Numb* value)
{
Trace("mono_mul_coeff");
assert(mono_is_valid(mono));
assert(numb_is_valid(value));
numb_mul(mono->coeff, value);
}
void mono_add_coeff(const Mono* mono, const Numb* value)
{
Trace("mono_add_coeff");
assert(mono_is_valid(mono));
assert(numb_is_valid(value));
numb_add(mono->coeff, value);
}
unsigned int mono_hash(const Mono* mono)
{
size_t hcode = 0;
const MonoElem* e;
assert(mono_is_valid(mono));
for(e = &mono->first; e != NULL; e = e->next)
hcode += ((size_t)entry_get_var(e->entry)) >> 2;
return DISPERSE((unsigned int)hcode);
}
/** Checks whether two monoms cosist of the same variables.
*/
#if 1
/* We assume (I think it is true that there is only one distinct entry per var
*/
bool mono_equal(const Mono* ma, const Mono* mb)
{
const MonoElem* ea;
const MonoElem* eb;
assert(mono_is_valid(ma));
assert(mono_is_valid(mb));
if (ma->count != mb->count)
return false;
if (ma->count == 1 && (ma->first.entry != mb->first.entry))
return false;
for(ea = &ma->first; ea != NULL; ea = ea->next)
{
const Entry* entry_a = ea->entry;
assert(entry_is_valid(entry_a));
assert(entry_get_type(entry_a) == SYM_VAR);
for(eb = &mb->first; eb != NULL; eb = eb->next)
if (entry_a == eb->entry)
break;
if (eb == NULL)
return false;
/* Now all variables of a kind are consecutive
*/
while(ea->next != NULL && ea->next->entry == entry_a)
{
if (eb->next == NULL || eb->next->entry != entry_a)
return false;
ea = ea->next; /*lint !e850 loop index variable is modified in body of the loop */
eb = eb->next;
}
}
return true;
}
#else /* old */
bool mono_equal(const Mono* ma, const Mono* mb)
{
const MonoElem* ea;
const MonoElem* eb;
Var* var_a;
assert(mono_is_valid(ma));
assert(mono_is_valid(mb));
if (ma->count != mb->count)
return false;
if (ma->count == 1 && (entry_get_var(ma->first.entry) != entry_get_var(mb->first.entry)))
return false;
for(ea = &ma->first; ea != NULL; ea = ea->next)
{
assert(entry_is_valid(ea->entry));
var_a = entry_get_var(ea->entry);
for(eb = &mb->first; eb != NULL; eb = eb->next)
if (var_a == entry_get_var(eb->entry))
break;
if (eb == NULL)
return false;
/* Now all variables of a kind are consecutive
*/
while(ea->next != NULL && entry_get_var(ea->next->entry) == var_a)
{
if (eb->next == NULL || entry_get_var(eb->next->entry) != var_a)
return false;
ea = ea->next;
eb = eb->next;
}
}
return true;
}
#endif
Mono* mono_mul(const Mono* ma, const Mono* mb)
{
Mono* mono;
const MonoElem* eb;
assert(mono_is_valid(ma));
assert(mono_is_valid(mb));
mono = mono_copy(ma);
numb_mul(mono->coeff, mb->coeff);
for(eb = &mb->first; eb != NULL; eb = eb->next)
{
assert(entry_is_valid(eb->entry));
mono_mul_entry(mono, eb->entry);
}
assert(mono_is_valid(mono));
return mono;
}
void mono_neg(Mono* mono)
{
assert(mono_is_valid(mono));
numb_neg(mono->coeff);
}
bool mono_is_linear(const Mono* mono)
{
assert(mono_is_valid(mono));
/* ??? Effect not fully testet */
return mono->count == 1 && (mono->fun == MFUN_NONE || mono->fun == MFUN_TRUE || mono->fun == MFUN_FALSE);
}
int mono_get_degree(const Mono* mono)
{
assert(mono_is_valid(mono));
return mono->count;
}
const Numb* mono_get_coeff(const Mono* mono)
{
assert(mono_is_valid(mono));
return mono->coeff;
}
void mono_set_function(Mono* mono, MFun f)
{
assert(mono_is_valid(mono));
mono->fun = f;
assert(mono_is_valid(mono));
}
MFun mono_get_function(const Mono* mono)
{
assert(mono_is_valid(mono));
return mono->fun;
}
Var* mono_get_var(const Mono* mono, int idx)
{
const MonoElem* e = &mono->first;
assert(mono_is_valid(mono));
assert(mono->count > 0);
assert(idx >= 0);
assert(idx <= mono->count);
if (idx > 0)
{
for(e = e->next; --idx > 0; e = e->next) /*lint !e441 loop variable 'e' not found in 2nd expression */
assert(e != NULL);
assert(e != NULL);
}
assert(entry_is_valid(e->entry));
return entry_get_var(e->entry);
}
#ifndef NDEBUG
void mono_print(FILE* fp, const Mono* mono, bool print_symbol_index)
{
const MonoElem* e;
assert(mono_is_valid(mono));
if (numb_equal(mono->coeff, numb_one()))
fputc('+', fp);
else
{
if (numb_cmp(mono->coeff, numb_zero()) >= 0)
fprintf(fp, "+ %g", numb_todbl(mono->coeff));
else
fprintf(fp, "- %g", -numb_todbl(mono->coeff));
}
fputc(' ', fp);
for(e = &mono->first; e != NULL; e = e->next)
{
entry_print(fp, e->entry);
if (print_symbol_index)
tuple_print(fp, entry_get_tuple(e->entry));
if (e->next != NULL)
fprintf(fp, " * ");
}
}
#endif /* !NDEBUG */
zimpl-3.3.6/src/zimpl/mme.h 0000644 0014172 0006025 00000010154 13304236715 015433 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: mme.h */
/* Name....: Mathematical Modelling Engine */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _MME_H_
#define _MME_H_
#ifdef __cplusplus
extern "C" {
#endif
#define ZIMPL_VERSION 336
/* the following is not in code.h because code.h needs mme.h anyway,
* but we also need these declaratons.
*/
enum code_type
{
CODE_ERR = 0, CODE_NUMB, CODE_STRG, CODE_NAME, CODE_TUPLE,
CODE_SET, CODE_TERM, CODE_BOOL, CODE_SIZE,
CODE_IDXSET, CODE_LIST, CODE_VOID, CODE_ENTRY, CODE_VARCLASS, CODE_CONTYPE,
CODE_RDEF, CODE_RPAR, CODE_BITS, CODE_SYM, CODE_DEF, CODE_BOUND
};
enum symbol_type { SYM_ERR = 0, SYM_NUMB, SYM_STRG, SYM_SET, SYM_VAR };
typedef enum symbol_type SymbolType;
typedef struct symbol Symbol;
typedef enum code_type CodeType;
typedef struct code_node CodeNode;
typedef CodeNode* (*Inst)(CodeNode* self);
typedef struct entry Entry;
typedef struct list_element ListElem;
typedef struct list List;
typedef enum var_type VarType; /* From ratlptypes.h */
typedef struct mono Mono; /* From mono.h */
#define SYMBOL_NAME_INTERNAL "@@"
#define VERB_QUIET 0
#define VERB_NORMAL 1
#define VERB_VERBOSE 2
#define VERB_CHATTER 3
#define VERB_DEBUG 5
/* zimpllib.c
*/
extern int verbose;
/*lint -function(exit,zpl_exit) */
extern void zpl_exit(int retval);
/* source.c
*/
/*lint -sem( show_source, nulterm(2), 1p == 1 && 2p) */
extern void show_source(FILE* fp, const char* text, int column);
/* vinst.c
*/
extern void interns_init(void);
extern void interns_exit(void);
#define Min(a, b) (((a) <= (b)) ? (a) : (b))
#define Sgn(a) (((a) > 0) ? 1 : (((a) < 0) ? -1 : 0))
/* Directory separator, so we could redefine it for Windoof.
*/
#ifndef DIRSEP
#define DIRSEP '/'
#endif /* DIRSEP */
#ifndef NDEBUG
#define SID unsigned int sid;
#define SID_set(p, id) (p->sid = id)
#define SID_del(p) (p->sid = 0xffffffff)
#define SID_ok(p, id) (p->sid == id)
#define SID_set2(p, id) (p.sid = id)
#define SID_del2(p) (p.sid = 0xffffffff)
#define SID_ok2(p, id) (p.sid == id)
#else /* NDEBUG */
#define SID /* */
#define SID_set(p, sid) /* */
#define SID_del(p) /* */
#define SID_ok(p, id) true
#define SID_set2(p, sid) /* */
#define SID_del2(p) /* */
#define SID_ok2(p, id) true
#endif /* NDEBUG */
#define DISPERSE(x) (1664525U * (x) + 1013904223U)
#ifdef TRACE
#define Trace(fname) fprintf(stderr, "Trace: %s\n", fname);
#else
#define Trace(fname) /* */
#endif /* TRACE */
#if defined(__GNUC__) || defined(__CLANG__)
#define UNUSED __attribute__ ((unused))
#define NORETURN __attribute__ ((noreturn))
#else
#define UNUSED
#define NORETURN
#endif /* __GNUC__ || __CLANG__ */
#ifdef __cplusplus
}
#endif
#endif /* _MME_H_ */
zimpl-3.3.6/src/zimpl/set4.h 0000644 0014172 0006025 00000020037 13304236715 015535 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: set4.h */
/* Name....: Set Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _SET4_H_
#define _SET4_H_
#ifdef __cplusplus
extern "C" {
#endif
enum set_type {
SET_ERROR = 0,
SET_EMPTY = 1, /* dim = ?, Empty Set */
SET_PSEUDO = 2, /* dim = 0, Has only empty tuple as element */
SET_LIST = 3, /* dim = 1, Explicit enumeration of members */
SET_RANGE = 4, /* dim = 1, Range: Start to End by Increment */
SET_PROD = 5, /* dim > 1, Cross Product of two or more sets */
SET_MULTI = 6, /* dim > 1, Multidimensional Subset */
SET_UNION = 7, /* dim > 1, Union of two sets */
SET_INTER = 8, /* dim > 1, Intersection of two sets */
SET_MINUS = 9, /* dim > 1, Subtraction of two sets */
SET_SYMDIFF = 10, /* dim > 1, Symetric difference of two sets */
SET_TYPES = 11 /* marker */
};
typedef enum set_type SetType;
typedef struct set_vtab SetVTab;
typedef struct set_empty SetEmpty;
typedef struct set_pseudo SetPseudo;
typedef struct set_head SetHead;
typedef struct set_list SetList;
typedef struct set_range SetRange;
typedef struct set_prod SetProd;
typedef struct set_multi SetMulti;
typedef struct set_empty_iter SetEmptyIter;
typedef struct set_pseudo_iter SetPseudoIter;
typedef struct set_list_iter SetListIter;
typedef struct set_range_iter SetRangeIter;
typedef struct set_prod_iter SetProdIter;
typedef struct set_multi_iter SetMultiIter;
struct set_head
{
int refc;
int dim;
SetIterIdx members;
SetType type;
};
struct set_empty
{
SetHead head;
SID
};
struct set_pseudo
{
SetHead head;
SID
};
struct set_list
{
SetHead head; /** head.dim == 1 */
int size;
Elem** member; /** head.members gives the number */
Hash* hash;
SID
};
struct set_range
{
SetHead head; /** head.dim == 1 */
int begin;
int end;
int step;
SID
};
struct set_prod
{
SetHead head; /** head.dim > 1 */
Set* set_a;
Set* set_b;
SID
};
/* set consists of dim list set that contain the elements of the tuples to be stored
* subset is an array with consists of
*/
struct set_multi
{
SetHead head; /* head.dim > 1 */
Set** set; /* dim times, type == SET_LIST */
SetIterIdx* subset; /* members * dim */
SetIterIdx** order; /* dim * members */
SID
};
union set
{
SetHead head;
SetEmpty empty;
SetPseudo pseudo;
SetList list;
SetRange range;
SetProd prod;
SetMulti multi;
};
struct set_empty_iter
{
int dummy;
SID
};
struct set_pseudo_iter
{
bool first;
SID
};
struct set_list_iter
{
int first;
int last;
int now;
SID
};
struct set_range_iter
{
int first;
int last;
int now;
SID
};
struct set_prod_iter
{
bool first;
SetIter* iter_a;
SetIter* iter_b;
Elem** elem;
SID
};
struct set_multi_iter
{
int dim;
SetIterIdx members;
SetIterIdx now;
SetIterIdx* subset;
SID
};
union set_iter
{
SetEmptyIter empty;
SetPseudoIter pseudo;
SetListIter list;
SetRangeIter range;
SetProdIter prod;
SetMultiIter multi;
};
struct set_vtab
{
void (*set_free) (Set* set);
Set* (*set_copy) (const Set* set);
SetIterIdx (*set_lookup_idx)(const Set* set, const Tuple* tuple, int offset);
void (*set_get_tuple) (const Set* set, SetIterIdx idx, Tuple* tuple, int offset);
SetIter* (*iter_init) (const Set* set, const Tuple* pattern, int offset);
bool (*iter_next) (SetIter* iter, const Set* set, Tuple* tuple, int offset);
void (*iter_exit) (SetIter* iter, const Set* set);
void (*iter_reset) (SetIter* iter, const Set* set);
bool (*set_is_valid) (const Set* set);
};
#define SET_DEFAULT 0x0
#define SET_NO_HASH 0x1
#ifdef NDEBUG
extern SetVTab* set_vtab_global;
#endif
/* set4.c
*/
/*lint -sem( set_lookup_idx, 1p == 1 && 2p == 1 && 3n >= 0, @n >= -1) */
extern SetIterIdx set_lookup_idx(const Set* set, const Tuple* tuple, int offset);
/*lint -sem( set_get_tuple_intern, 1p == 1 && 2n >= 0 && 3p == 1 && 4n >= 0) */
extern void set_get_tuple_intern(const Set* set, SetIterIdx idx, Tuple* tuple, int offset);
/*lint -sem( set_iter_init_intern, 1p == 1 && 3n >= 0, @P > malloc(1P)) */
extern SetIter* set_iter_init_intern(const Set* set, const Tuple* pattern, int offset);
/*lint -sem( set_iter_next_intern, 1p == 1 && 2p == 1 && 3p == 1 && 4n >= 0) */
extern bool set_iter_next_intern(SetIter* iter, const Set* set, Tuple* tuple, int offset);
/*lint -sem( set_iter_exit_intern, custodial(1), 1p == 1 && 2p == 1) */
extern void set_iter_exit_intern(SetIter* iter, const Set* set);
/*lint -sem( set_iter_reset_intern, 1p == 1 && 2p == 1) */
extern void set_iter_reset_intern(SetIter* iter, const Set* set);
/* setempty.c
*/
/*lint -sem( set_empty_init, 1p == SET_TYPES) */
extern void set_empty_init(SetVTab* vtab);
/* setpseudo.c
*/
/*lint -sem( set_pseudo_init, 1p == SET_TYPES) */
extern void set_pseudo_init(SetVTab* vtab);
/* setlist.c
*/
/*lint -sem( set_list_init, 1p == SET_TYPES) */
extern void set_list_init(SetVTab* vtab);
/*lint -sem( set_list_new, 1n > 0 && 2n >= 0, @P > malloc(1P)) */
extern Set* set_list_new(int size, int flags);
/*lint -sem( set_list_add_elem, 1p == 1 && 2p == 1, @n >= -1) */
extern SetIterIdx set_list_add_elem(Set* set, const Elem* elem, SetCheckType check);
/*lint -sem( set_list_new_from_elems, 1p == 1, @P > malloc(1P)) */
extern Set* set_list_new_from_elems(const List* list, SetCheckType check);
/*lint -sem( set_list_new_from_tuples, 1p == 1, @P > malloc(1P)) */
extern Set* set_list_new_from_tuples(const List* list, SetCheckType check);
/*lint -sem( set_list_new_from_entries, 1p == 1, @P > malloc(1P)) */
extern Set* set_list_new_from_entries(const List* list, SetCheckType check);
/*lint -sem( set_list_get_elem, 1p == 1 && 2n >= 0, @P > malloc(1P)) */
extern const Elem* set_list_get_elem(const Set* set, SetIterIdx idx);
/* setrange.c
*/
/*lint -sem( set_range_init, 1p == SET_TYPES) */
extern void set_range_init(SetVTab* vtab);
/* setprod.c
*/
/*lint -sem( set_prod_init, 1p == SET_TYPES) */
extern void set_prod_init(SetVTab* vtab);
/* set multi.c
*/
/*lint -sem( set_multi_init, 1p == SET_TYPES) */
extern void set_multi_init(SetVTab* vtab);
/*lint -sem( set_multi_new_from_list, 1p == 1, @P > malloc(1P)) */
extern Set* set_multi_new_from_list(const List* list, SetCheckType check);
#ifdef __cplusplus
}
#endif
#endif /* _SET4_H_ */
zimpl-3.3.6/src/zimpl/entry.c 0000644 0014172 0006025 00000013745 13304236715 016022 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: entry.c */
/* Name....: Symbol Table Entry Functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2001-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include
#include
#include
#include "zimpl/mshell.h"
#include "zimpl/ratlptypes.h"
#include "zimpl/numb.h"
#include "zimpl/elem.h"
#include "zimpl/tuple.h"
#include "zimpl/mme.h"
#include "zimpl/set.h"
#include "zimpl/symbol.h"
#include "zimpl/entry.h"
#include "zimpl/zimpllib.h"
#define ENTRY_SID 0x456e7472
typedef union entry_value EntryValue;
union entry_value
{
Numb* numb;
const char* strg;
Set* set;
Var* var;
};
struct entry
{
SID
int refc;
Tuple* tuple;
SymbolType type;
EntryValue value;
};
Entry* entry_new_numb(const Tuple* tuple, const Numb* numb)
{
Entry* entry = calloc(1, sizeof(*entry));
assert(entry != NULL);
assert(tuple != NULL);
entry->refc = 1;
entry->tuple = tuple_copy(tuple);
entry->type = SYM_NUMB;
entry->value.numb = numb_copy(numb);
SID_set(entry, ENTRY_SID);
assert(entry_is_valid(entry));
mem_check(entry);
return entry;
}
Entry* entry_new_strg(const Tuple* tuple, const char* strg)
{
Entry* entry = calloc(1, sizeof(*entry));
assert(entry != NULL);
assert(tuple != NULL);
assert(strg != NULL);
entry->refc = 1;
entry->tuple = tuple_copy(tuple);
entry->type = SYM_STRG;
entry->value.strg = strg;
SID_set(entry, ENTRY_SID);
assert(entry_is_valid(entry));
return entry;
}
Entry* entry_new_set(const Tuple* tuple, const Set* set)
{
Entry* entry = calloc(1, sizeof(*entry));
assert(entry != NULL);
assert(tuple != NULL);
assert(set != NULL);
entry->refc = 1;
entry->tuple = tuple_copy(tuple);
entry->type = SYM_SET;
entry->value.set = set_copy(set);
SID_set(entry, ENTRY_SID);
assert(entry_is_valid(entry));
return entry;
}
Entry* entry_new_var(const Tuple* tuple, Var* var)
{
Entry* entry = calloc(1, sizeof(*entry));
assert(entry != NULL);
assert(tuple != NULL);
assert(var != NULL);
entry->refc = 1;
entry->tuple = tuple_copy(tuple);
entry->type = SYM_VAR;
entry->value.var = var;
SID_set(entry, ENTRY_SID);
assert(entry_is_valid(entry));
return entry;
}
void entry_free(Entry* entry)
{
assert(entry_is_valid(entry));
entry->refc--;
if (entry->refc == 0)
{
SID_del(entry);
switch(entry->type)
{
case SYM_NUMB :
numb_free(entry->value.numb);
break;
case SYM_STRG :
break;
case SYM_SET :
set_free(entry->value.set);
break;
case SYM_VAR :
break;
default :
abort();
}
tuple_free(entry->tuple);
free(entry);
}
}
bool entry_is_valid(const Entry* entry)
{
if (entry == NULL || !SID_ok(entry, ENTRY_SID))
return false;
mem_check(entry);
return true;
}
Entry* entry_copy(const Entry* source)
{
Entry* entry = (Entry*)source;
assert(entry_is_valid(entry));
entry->refc++;
return entry;
}
bool entry_cmp(const Entry* entry, const Tuple* tuple)
{
assert(entry_is_valid(entry));
assert(tuple_is_valid(tuple));
return tuple_cmp(entry->tuple, tuple);
}
SymbolType entry_get_type(const Entry* entry)
{
assert(entry_is_valid(entry));
return entry->type;
}
const Tuple* entry_get_tuple(const Entry* entry)
{
assert(entry_is_valid(entry));
assert(tuple_is_valid(entry->tuple));
return entry->tuple;
}
const Numb* entry_get_numb(const Entry* entry)
{
assert(entry_is_valid(entry));
assert(entry->type == SYM_NUMB);
return entry->value.numb;
}
const char* entry_get_strg(const Entry* entry)
{
assert(entry_is_valid(entry));
assert(entry->type == SYM_STRG);
return entry->value.strg;
}
const Set* entry_get_set(const Entry* entry)
{
assert(entry_is_valid(entry));
assert(entry->type == SYM_SET);
return entry->value.set;
}
Var* entry_get_var(const Entry* entry)
{
assert(entry_is_valid(entry));
assert(entry->type == SYM_VAR);
return entry->value.var;
}
void entry_print(FILE* fp, const Entry* entry)
{
assert(entry_is_valid(entry));
tuple_print(fp, entry->tuple);
fprintf(fp, " -> ");
switch(entry->type)
{
case SYM_NUMB :
fprintf(fp, "%.16g", numb_todbl(entry->value.numb));
break;
case SYM_STRG :
fprintf(fp, "\"%s\"", entry->value.strg);
break;
case SYM_SET :
set_print(fp, entry->value.set);
break;
case SYM_VAR :
zpl_var_print(fp, entry->value.var);
break;
default :
fprintf(fp, "Entry-ERR");
break;
}
}
zimpl-3.3.6/src/zimpl/ratlpstore.h 0000644 0014172 0006025 00000010040 13304236715 017046 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: ratlpstore.h */
/* Name....: Rational Number Store Linear Programm */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2003-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _RATLPSTORE_H_
#define _RATLPSTORE_H_
#ifndef __GMP_H__
#error "Need to include gmp.h before ratlpstore.h"
#endif
#ifndef _RATLPTYPES_H_
#error "Need to include ratlptypes.h before ratlpstore.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct storage Sto;
typedef struct lps_hash LpsHash;
struct nonzero
{
Var* var;
Con* con;
Nzo* var_prev;
Nzo* var_next;
Nzo* con_prev;
Nzo* con_next;
mpq_t value;
};
struct variable
{
unsigned int sid;
char* name;
int number;
VarClass vclass;
VarType type;
bool is_used;
int size;
mpq_t cost;
mpq_t lower;
mpq_t upper;
mpq_t value;
mpq_t startval;
int priority;
Var* prev;
Var* next;
Nzo* first;
};
#define VAR_SID 0x5e564152
struct constraint
{
unsigned int sid;
char* name;
int number;
unsigned int flags;
ConType type;
int size;
mpq_t lhs;
mpq_t rhs;
mpq_t scale;
Var* ind_var;
bool ind_dir;
Con* prev;
Con* next;
Nzo* first;
Qme* qme_first;
Term* term;
};
#define CON_SID 0x5e434f4e
struct lpstorage
{
char* name;
LpType type; /* ??? Wird noch nicht automatisch gesetzt */
LpDirect direct;
char* probname;
char* objname;
char* rhsname;
char* bndname;
char* rngname;
int vars;
int cons;
int soss;
int nonzeros;
Var* var_root;
Con* con_root;
Sos* sos_root;
Sto* sto_root;
Nzo* next;
LpsHash* var_hash;
LpsHash* con_hash;
LpsHash* sos_hash;
Var* var_last;
Con* con_last;
Sos* sos_last;
int name_len;
};
struct soselement
{
Var* var;
mpq_t weight;
Sse* next;
};
struct soset
{
unsigned int sid;
char* name;
SosType type;
int priority;
int sses;
Sos* next;
Sse* first;
};
#define SOS_SID 0x5e534f53
struct qmatentry
{
unsigned int sid;
const Var* var1;
const Var* var2;
mpq_t value;
Qme* next;
};
#define QME_SID 0x514D656E
/* Internal functions
*/
/*lint -sem( lps_getnamesize, 1p, @n > 8) */
int lps_getnamesize(const Lps* lp, LpFormat format);
/*lint -sem( lps_makename, nulterm(3), 1p && 2n > 0 && 3p && 4n >= -1) */
void lps_makename(char* target, int size, const char* name, int no);
#ifdef __cplusplus
}
#endif
#endif /* _RATLPSTORE_H_ */
zimpl-3.3.6/src/zimpl/gmpmisc.c 0000644 0014172 0006025 00000014436 13304236715 016316 0 ustar bzfschlo optimi /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* File....: ratmisc.c */
/* Name....: miscellenious rational arithmetic functions */
/* Author..: Thorsten Koch */
/* Copyright by Author, All rights reserved */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Copyright (C) 2003-2018 by Thorsten Koch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include
#include
#include