├── .gitignore
├── LICENSE
├── README.md
├── assembly.sbt
├── bin
└── publish.sh
├── build.sbt
├── canonicalCNF.py
├── project
├── build.properties
└── plugins.sbt
├── src
├── glucose-30-backbone
│ ├── README.md
│ ├── core
│ │ ├── BoundedQueue.h
│ │ ├── Constants.h
│ │ ├── Dimacs.h
│ │ ├── Main.cc
│ │ ├── Makefile
│ │ ├── Solver.cc
│ │ ├── Solver.h
│ │ └── SolverTypes.h
│ ├── mtl
│ │ ├── Alg.h
│ │ ├── Alloc.h
│ │ ├── Heap.h
│ │ ├── IntTypes.h
│ │ ├── Map.h
│ │ ├── Queue.h
│ │ ├── Sort.h
│ │ ├── Vec.h
│ │ ├── XAlloc.h
│ │ ├── config.mk
│ │ └── template.mk
│ └── utils
│ │ ├── Makefile
│ │ ├── Options.cc
│ │ ├── Options.h
│ │ ├── ParseUtils.h
│ │ ├── System.cc
│ │ └── System.h
└── main
│ └── java
│ └── tuffy
│ ├── db
│ ├── RDB.java
│ ├── SQLMan.java
│ └── package.html
│ ├── ground
│ ├── Grounding.java
│ ├── KBMC.java
│ ├── package.html
│ ├── package_grounding.jpeg
│ └── partition
│ │ ├── Component.java
│ │ ├── Partition.java
│ │ ├── PartitionScheme.java
│ │ ├── Partitioning.java
│ │ └── package.html
│ ├── helper
│ ├── Stats.java
│ └── package.html
│ ├── infer
│ ├── DataMover.java
│ ├── MRF.java
│ ├── PGInfer.java
│ ├── ds
│ │ ├── GAtom.java
│ │ ├── GClause.java
│ │ ├── KeyBlock.java
│ │ └── package.html
│ ├── package.html
│ └── package_infer.jpeg
│ ├── main
│ ├── Infer.java
│ ├── Main.java
│ ├── NonPartInfer.java
│ └── package.html
│ ├── mln
│ ├── Atom.java
│ ├── Clause.java
│ ├── Literal.java
│ ├── MarkovLogicNetwork.java
│ ├── Predicate.java
│ ├── Term.java
│ ├── Tuple.java
│ ├── Type.java
│ ├── package.html
│ └── package_mln.jpeg
│ ├── parse
│ ├── CommandOptions.java
│ ├── Config.g
│ ├── Config.tokens
│ ├── ConfigLexer.java
│ ├── ConfigParser.java
│ ├── InputParser.java
│ ├── MLN.g
│ ├── MLN.tokens
│ ├── MLNLexer.java
│ ├── MLNParser.java
│ ├── antlr-home
│ │ └── lib
│ │ │ └── antlr-3.2.jar
│ └── package.html
│ ├── ra
│ ├── AtomEx.java
│ ├── ConjunctiveQuery.java
│ ├── Expression.java
│ ├── Function.java
│ └── package.html
│ ├── test
│ ├── AtomTest.java
│ ├── ClauseTest.java
│ ├── ConfigTest.java
│ ├── GAtomTest.java
│ ├── GClauseTest.java
│ ├── GroundingTest.java
│ ├── InferenceTest.java
│ ├── InferenceTest.java.stale
│ ├── LiteralTest.java
│ ├── ParsingLoadingTest.java
│ ├── PredicateTest.java
│ ├── TermTest.java
│ ├── TupleTest.java
│ ├── TypeTest.java
│ └── package.html
│ ├── util
│ ├── BatMan.java
│ ├── BitSetDoublePair.java
│ ├── BitSetIntPair.java
│ ├── BoundHashList.java
│ ├── Config.java
│ ├── DebugMan.java
│ ├── DeterministicMapHelper.java
│ ├── Enumerator.java
│ ├── ExceptionMan.java
│ ├── FileMan.java
│ ├── HashArray.java
│ ├── IronMan.java
│ ├── MathMan.java
│ ├── PlotMan.java
│ ├── ProbMan.java
│ ├── SeededRandom.java
│ ├── Settings.java
│ ├── SpiderMan.java
│ ├── Stats.java
│ ├── StringMan.java
│ ├── SuperMan.java
│ ├── Timer.java
│ ├── TuffyThrownError.java
│ ├── UIMan.java
│ ├── UnionFind.java
│ ├── myDouble.java
│ ├── myInt.java
│ ├── package.html
│ └── runAllTestCases.java
│ └── worker
│ └── ds
│ └── MLEWorld.java
└── version.sbt
/.gitignore:
--------------------------------------------------------------------------------
1 | .cache
2 | .classpath
3 | .history
4 | .project
5 | .settings
6 |
7 | # Ignore any bin directory in the project root.
8 | bin/**
9 | logs/
10 |
11 | # sbt specific
12 | target/
13 |
14 | # intellij stuff
15 | .idea
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TuffyLite [](https://semaphoreci.com/allenai/tuffylite)
2 |
3 | TuffyLite is a modified version of the open source [Tuffy solver](http://hazy.cs.wisc.edu/hazy/tuffy) for performing inference with Markov Logic Networks (MLNs). Specifically, it is an inference-only variant of [Tuffy version 0.3](http://hazy.cs.wisc.edu/hazy/tuffy/download/tuffy-src-0.3-mar2014.zip) implementing the changes described in the following paper:
4 |
5 | > [Markov Logic Networks for Natural Language Question Answering](http://arxiv.org/abs/1507.03045). Tushar Khot, Niranjan Balasubramanian, Eric Gribkoff, Ashish Sabharwal, Peter Clark, Oren Etzioni. StarAI-2015, 5th International Workshop on Statistical Relational AI, Amsterdam, The Netherlands, July 2015.
6 |
7 | For more information about MLNs and the kinds of problems Tuffy is suitable for, please refer to the original Tuffy solver. The main changes to Tuffy implemented in TuffyLite are described below.
8 |
9 | This project also includes minor modifications to the [Glucose 3.0 SAT Solver](http://www.labri.fr/perso/lsimon/glucose) to identify variables with fixed values by unit propagation, backbone detection, or equivalence detection. This information is (optionally) used by TuffyLite iteratively to simplify and often vastly reduce the size of the grounding of hard and soft constraints by exploiting structure imposed by hard constraints.
10 |
11 |
12 | ## List of Modifications
13 |
14 | The main additions to Tuffy include:
15 |
16 | * Iterative Unit Propagation and Backbone Detection when grounding an MLN: after grounding each hard rule, we run unit propagation (or, optionally, use backbone detection) to identify literals with fixed values, simplify the current grounding, and reduce the size of the groundings of subsequent hard and soft rules. Please see the above referenced paper for more details.
17 |
18 | * Re-implementation of MC-SAT/SampleSAT algorithm for sampling from a ground MRF: some parts of the code in Tuffy had diverged from the standard SampleSAT algorithm, and the reimplementation yielded improved inference quality on some problems.
19 |
20 | * Ability to run the code completely deterministically: random number seeds for Java and Postgres are now config options.
21 |
22 | * Ability to specify a time limit.
23 |
24 | * Bug fix when grounding existential quantifiers.
25 |
26 | * Several output file options, including writing the ground MRF in human-readable or WCNF file format.
27 |
28 | * Some other minor changes to default config options, disabling some heuristics such as "greedy throttling" which can make the underlying SampleSAT algorithm non-uniform.
29 |
30 | On the down side, TuffyLite focuses mainly on the inference aspect, especially marginal inference, and currently does not support the following:
31 |
32 | * No weight learning.
33 |
34 | * No partitioned grounding and inference.
35 |
36 |
37 | ## Contact
38 |
39 | Please contact [Eric Gribkoff](http://homes.cs.washington.edu/~eagribko) or [Ashish Sabharwal](http://ashishs.people.allenai.org) if you have any questions or comments.
40 |
41 |
--------------------------------------------------------------------------------
/assembly.sbt:
--------------------------------------------------------------------------------
1 | mainClass in assembly := Some("tuffy.main.Main")
2 |
3 | // your assembly settings here
4 | jarName := "tuffy.jar"
5 |
--------------------------------------------------------------------------------
/bin/publish.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # Publish to BinTray if the HEAD commit is tagged with a version number.
6 | if [ "$PULL_REQUEST_NUMBER" ]; then
7 | echo "Semaphore is building a pull request, not publishing."
8 | echo "PULL_REQUEST_NUMBER is equal to $PULL_REQUEST_NUMBER"
9 | exit 0
10 | fi
11 |
12 | if [ "$BRANCH_NAME" != "master" ]; then
13 | echo "Semaphore is building on branch $BRANCH_NAME, not publishing."
14 | echo "BRANCH_NAME is equal to $BRANCH_NAME"
15 | exit 0
16 | fi
17 |
18 | numParents=`git log --pretty=%P -n 1 | wc -w | xargs`
19 | if [ $numParents -ne 2 ]; then
20 | echo "$numParents parent commits of HEAD when exactly 2 expected, not publishing."
21 | exit 0
22 | fi
23 |
24 | # One build is run for the merge to master, so we need to list all tags from the merged commits.
25 | firstMergedCommit=`git rev-list HEAD^2 --not HEAD^1 | tail -n 1`
26 | echo "First merged commit: $firstMergedCommit"
27 |
28 | tags=$(git tag --contains $firstMergedCommit)
29 |
30 | if [ `echo "$tags" | wc -l` -eq 0 ]; then
31 | echo "No tags found in merged commits, not publishing."
32 | exit 0
33 | fi
34 |
35 | if [ `echo "$tags" | wc -l` -gt 1 ]; then
36 | echo "Multiple tags found in merged commits, not publishing."
37 | echo "$tags"
38 | exit 0
39 | fi
40 |
41 | tag=$tags
42 |
43 | echo "Merged commits contain tag: $tag"
44 |
45 | if [[ $tag =~ ^v[0-9]+\..* ]]; then
46 | echo "Going to release from tag $tag"
47 | version=$(echo $tag | sed -e s/^v//)
48 |
49 | git checkout $tag
50 | sbt publish
51 | echo "Successfully published artifact."
52 |
53 | exit 0
54 | fi
55 |
--------------------------------------------------------------------------------
/build.sbt:
--------------------------------------------------------------------------------
1 | import org.allenai.plugins.CoreRepositories.Licenses
2 |
3 | lazy val buildSettings = Seq(
4 | organization := "edu.stanford.hazy",
5 | description := "An internal version of Tuffy downloaded from: http://i.stanford.edu/hazy/tuffy/download/",
6 | publishMavenStyle := true,
7 | publishArtifact in (Compile, packageDoc) := false, // to avoid "javadoc: error - invalid flag: -target"
8 | licenses += Licenses.apache2,
9 | homepage := Some(url("https://github.com/allenai/tuffylite")),
10 | scmInfo := Some(ScmInfo(
11 | url("https://github.com/allenai/tuffylite"),
12 | "https://github.com/allenai/tuffylite.git")),
13 | pomExtra := (
14 |
15 |
16 | allenai-dev-role
17 | Allen Institute for Artificial Intelligence
18 | dev-role@allenai.org
19 |
20 | ),
21 | // TODO (colinarenz): When this is included in sbt-plugins, it can be removed.
22 | bintrayOrganization := Some("allenai")
23 | )
24 |
25 | lazy val tuffy = Project(id = "tuffy-internal", base = file("."))
26 | .settings(buildSettings)
27 | .settings(PublishTo.ai2BintrayPublic)
28 |
29 | resolvers ++= Seq(
30 | "scala-tools.org" at "http://scala-tools.org/repo-releases",
31 | "conjars" at "http://conjars.org/repo",
32 | "apache.releases" at "https://repository.apache.org/content/repositories/releases"
33 | )
34 |
35 | libraryDependencies ++= Seq(
36 | "args4j" % "args4j" % "2.0.16",
37 | "junit" % "junit" % "4.11",
38 | "org.antlr" % "antlr" % "3.2",
39 | "org.apache.commons" % "commons-lang3" % "3.3",
40 | "org.apache.commons" % "commons-math" % "2.2",
41 | "org.postgresql" % "postgresql" % "9.3-1102-jdbc41",
42 | "thirdparty" % "jgrapht-jdk1.6" % "0.8.2"
43 | )
44 |
45 | compileOrder := CompileOrder.JavaThenScala
46 |
47 | javaOptions += "-Xmx4G"
48 | scalacOptions ++= Seq("-Xlint", "-deprecation", "-feature")
49 |
--------------------------------------------------------------------------------
/canonicalCNF.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import subprocess
3 |
4 | # Check_output() not defined in Python 2.6
5 | def check_output(*popenargs, **kwargs):
6 | if 'stdout' in kwargs:
7 | raise ValueError('stdout argument not allowed, it will be overridden.')
8 | process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
9 | output, unused_err = process.communicate()
10 | retcode = process.poll()
11 | if retcode:
12 | cmd = kwargs.get("args")
13 | if cmd is None:
14 | cmd = popenargs[0]
15 | raise subprocess.CalledProcessError(retcode, cmd, output=output)
16 | return output
17 |
18 | class CalledProcessError(Exception):
19 | def __init__(self, returncode, cmd, output=None):
20 | self.returncode = returncode
21 | self.cmd = cmd
22 | self.output = output
23 | def __str__(self):
24 | return "Command '%s' returned non-zero exit status %d" % (
25 | self.cmd, self.returncode)
26 | # overwrite CalledProcessError due to `output` keyword might be not available
27 | subprocess.CalledProcessError = CalledProcessError
28 |
29 | def reduceClause(clause, backbones):
30 | newClause = Clause(clause.weight)
31 | newClause.lits = filter(lambda l: -l not in backbones, clause.lits)
32 | return newClause
33 |
34 | class WCNF:
35 | def __init__(self, hard_weight):
36 | self.hard_weight = hard_weight
37 | self.clauses = [] #set()
38 | def setClauses(self, clauses):
39 | self.clauses = clauses
40 | def addClause(self,clause):
41 | self.clauses.append(clause) #add(clause)
42 | def applyBackbones(self, backbones):
43 | print backbones
44 | usefulClauses = filter(lambda c: not any([l in c.lits for l in backbones]), self.clauses)
45 | print usefulClauses
46 | reducedClauses = map(lambda c: reduceClause(c, backbones), usefulClauses)
47 | print reducedClauses
48 | self.clauses = reducedClauses
49 | def __str__(self):
50 | clauseList = [c for c in self.clauses]
51 | clauseList.sort(key=lambda x: x.weight)
52 | clauseList.sort(key=lambda x: x.__str__())
53 | return "Hard weight: %f\nNumber clauses: %d\nClauses:\n%s" \
54 | % (self.hard_weight, len(self.clauses), \
55 | "\n".join([c.__str__() for c in clauseList]))
56 |
57 | class Clause:
58 | def __init__(self,weight):
59 | self.weight=weight
60 | self.lits=[] #set()
61 | def addLiteral(self,lit):
62 | self.lits.append(lit) #add(lit)
63 | def __repr__(self):
64 | return "[" + " ".join([str(l) for l in self.lits]) + "]"
65 | def __str__(self):
66 | literalList = [l for l in self.lits]
67 | literalList.sort()
68 | return "Weight: %f Literals: %s" % (self.weight, \
69 | " ".join([str(l) for l in literalList]))
70 |
71 | def runGlucose(filename):
72 | output = check_output(
73 | "/home/ec2-user/glucose-3.0-backbone/core/glucose -printunits " \
74 | + filename + " | grep UNITS", shell=True
75 | )
76 | backbones = [int(l) for l in output.split(" ")[1:]]
77 | return backbones
78 |
79 | def readWCNF(filename):
80 | lines = [line.rstrip() for line in open(filename)]
81 | header = lines[0].split(" ")
82 | hard_weight = float(header[4])
83 |
84 | wcnf = WCNF(hard_weight)
85 |
86 | for i in range(1, len(lines)):
87 | (weight, rest) = lines[i].split(" ", 1)
88 | weight = float(weight)
89 | clause = Clause(weight)
90 | (lits, zero) = rest.rsplit(" ", 1)
91 | for l in lits.split(" "):
92 | clause.addLiteral(int(l))
93 | wcnf.addClause(clause)
94 |
95 | return wcnf
96 |
97 | def writeHardClausesToFile(wcnf, filename):
98 | f = open(filename, 'w')
99 | f.write("p cnf %d %d\n" % (1, len(wcnf.clauses)))
100 | for c in wcnf.clauses:
101 | if c.weight >= wcnf.hard_weight:
102 | f.write("%s 0\n" % (" ".join([str(l) for l in c.lits])))
103 | if c.weight <= -wcnf.hard_weight:
104 | print "uh oh"
105 | exit
106 |
107 | f.close()
108 |
109 | def reduceClauses(clauses, backbones):
110 | usefulClauses = filter(lambda c: not any([l in c for l in backbones]), clauses)
111 | reducedClauses = map(lambda c: filter(lambda l: -l not in backbones, c), usefulClauses)
112 | return reducedClauses
113 |
114 | wcnfFilename = sys.argv[1]
115 | cnfFilename = sys.argv[2]
116 | canonicalWcnfFilename = sys.argv[3]
117 | wcnf = readWCNF(wcnfFilename)
118 | writeHardClausesToFile(wcnf, cnfFilename)
119 | #print readWCNF(filename)
120 | backbones = runGlucose(cnfFilename)
121 | wcnf.applyBackbones(backbones)
122 | print wcnf
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=0.13.11
2 |
--------------------------------------------------------------------------------
/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("org.allenai.plugins" % "allenai-sbt-plugins" % "1.3.0")
2 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
3 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/README.md:
--------------------------------------------------------------------------------
1 | # Glucose 3.0 Solver modified for Unit Propagation and Backbone Detection
2 |
3 | This is a minor modification to the [Glucose 3.0 SAT Solver](http://www.labri.fr/perso/lsimon/glucose) that can be used to print out literals that have fixed values in the input formula, detected either by running Unit Propagation or by doing full Backbone Detection. The solver can also produce a list of pairs of equivalent literals: `x = y` or `x = NOT y`.
4 |
5 | To detect whether a variable `x` is a backbone for a CNF SAT formula `F`, the solver sets `x = False` as an "assumption" and checks whether `F` is still satisfiable. For an `N` variable formula, this process involves up to `2*N` calls to the SAT solving routine. Much of the work during these calls, however, is shared and reused due to the use of the "assumptions" functionality of Glucose.
6 |
7 | The output this solver is (optionally) used by TuffyLite to simplify the grounding of hard and soft constraints by exploiting structure imposed by hard constraints.
8 |
9 | Please refer to the [original Glucose 3.0 solver](http://www.labri.fr/perso/lsimon/glucose) for details about the kinds of problems it can solve.
10 |
11 | To compile, do: `cd core; make`. Note that a verison of `g++` at least as new as `4.4` may be needed, depending on your system. The code has been tested with versions `4.8` and `5.0`. Basic usage may be seen by running `glucose --help`. The new additions to Glucose are invoked using the following command-line options:
12 |
13 | ```
14 | NEW OPTIONS:
15 |
16 | -printunits, -no-printunits (default: off)
17 | -printbackbone, -no-printbackbone (default: off)
18 | -printequiv, -no-printequiv (default: off)
19 | ```
20 |
21 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/core/BoundedQueue.h:
--------------------------------------------------------------------------------
1 | /***********************************************************************************[BoundedQueue.h]
2 | Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon
3 | CRIL - Univ. Artois, France
4 | LRI - Univ. Paris Sud, France
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
7 | associated documentation files (the "Software"), to deal in the Software without restriction,
8 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
9 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all copies or
13 | substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
16 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
19 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | **************************************************************************************************/
21 |
22 |
23 | #ifndef BoundedQueue_h
24 | #define BoundedQueue_h
25 |
26 | #include "mtl/Vec.h"
27 |
28 | //=================================================================================================
29 |
30 | namespace Glucose {
31 |
32 | template
33 | class bqueue {
34 | vec elems;
35 | int first;
36 | int last;
37 | unsigned long long sumofqueue;
38 | int maxsize;
39 | int queuesize; // Number of current elements (must be < maxsize !)
40 | bool expComputed;
41 | double exp,value;
42 | public:
43 | bqueue(void) : first(0), last(0), sumofqueue(0), maxsize(0), queuesize(0),expComputed(false) { }
44 |
45 | void initSize(int size) {growTo(size);exp = 2.0/(size+1);} // Init size of bounded size queue
46 |
47 | void push(T x) {
48 | expComputed = false;
49 | if (queuesize==maxsize) {
50 | assert(last==first); // The queue is full, next value to enter will replace oldest one
51 | sumofqueue -= elems[last];
52 | if ((++last) == maxsize) last = 0;
53 | } else
54 | queuesize++;
55 | sumofqueue += x;
56 | elems[first] = x;
57 | if ((++first) == maxsize) {first = 0;last = 0;}
58 | }
59 |
60 | T peek() { assert(queuesize>0); return elems[last]; }
61 | void pop() {sumofqueue-=elems[last]; queuesize--; if ((++last) == maxsize) last = 0;}
62 |
63 | unsigned long long getsum() const {return sumofqueue;}
64 | unsigned int getavg() const {return (unsigned int)(sumofqueue/((unsigned long long)queuesize));}
65 | int maxSize() const {return maxsize;}
66 | double getavgDouble() const {
67 | double tmp = 0;
68 | for(int i=0;i
25 |
26 | #include "utils/ParseUtils.h"
27 | #include "core/SolverTypes.h"
28 |
29 | namespace Glucose {
30 |
31 | //=================================================================================================
32 | // DIMACS Parser:
33 |
34 | template
35 | static void readClause(B& in, Solver& S, vec& lits) {
36 | int parsed_lit, var;
37 | lits.clear();
38 | for (;;){
39 | parsed_lit = parseInt(in);
40 | if (parsed_lit == 0) break;
41 | var = abs(parsed_lit)-1;
42 | while (var >= S.nVars()) S.newVar();
43 | lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) );
44 | }
45 | }
46 |
47 | template
48 | static void parse_DIMACS_main(B& in, Solver& S) {
49 | vec lits;
50 | int vars = 0;
51 | int clauses = 0;
52 | int cnt = 0;
53 | for (;;){
54 | skipWhitespace(in);
55 | if (*in == EOF) break;
56 | else if (*in == 'p'){
57 | if (eagerMatch(in, "p cnf")){
58 | vars = parseInt(in);
59 | clauses = parseInt(in);
60 | // SATRACE'06 hack
61 | // if (clauses > 4000000)
62 | // S.eliminate(true);
63 | }else{
64 | printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
65 | }
66 | } else if (*in == 'c' || *in == 'p')
67 | skipLine(in);
68 | else{
69 | cnt++;
70 | readClause(in, S, lits);
71 | S.addClause_(lits); }
72 | }
73 | if (vars != S.nVars())
74 | fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of variables.\n");
75 | if (cnt != clauses)
76 | fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of clauses.\n");
77 | }
78 |
79 | // Inserts problem into solver.
80 | //
81 | template
82 | static void parse_DIMACS(gzFile input_stream, Solver& S) {
83 | StreamBuffer in(input_stream);
84 | parse_DIMACS_main(in, S); }
85 |
86 | //=================================================================================================
87 | }
88 |
89 | #endif
90 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/core/Makefile:
--------------------------------------------------------------------------------
1 | EXEC = glucose
2 | DEPDIR = mtl utils
3 | MROOT = $(PWD)/..
4 | include $(MROOT)/mtl/template.mk
5 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/Alg.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************************[Alg.h]
2 | Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3 | Copyright (c) 2007-2010, Niklas Sorensson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | associated documentation files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | **************************************************************************************************/
20 |
21 | #ifndef Glucose_Alg_h
22 | #define Glucose_Alg_h
23 |
24 | #include "mtl/Vec.h"
25 |
26 | namespace Glucose {
27 |
28 | //=================================================================================================
29 | // Useful functions on vector-like types:
30 |
31 | //=================================================================================================
32 | // Removing and searching for elements:
33 | //
34 |
35 | template
36 | static inline void remove(V& ts, const T& t)
37 | {
38 | int j = 0;
39 | for (; j < ts.size() && ts[j] != t; j++);
40 | assert(j < ts.size());
41 | for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
42 | ts.pop();
43 | }
44 |
45 |
46 | template
47 | static inline bool find(V& ts, const T& t)
48 | {
49 | int j = 0;
50 | for (; j < ts.size() && ts[j] != t; j++);
51 | return j < ts.size();
52 | }
53 |
54 |
55 | //=================================================================================================
56 | // Copying vectors with support for nested vector types:
57 | //
58 |
59 | // Base case:
60 | template
61 | static inline void copy(const T& from, T& to)
62 | {
63 | to = from;
64 | }
65 |
66 | // Recursive case:
67 | template
68 | static inline void copy(const vec& from, vec& to, bool append = false)
69 | {
70 | if (!append)
71 | to.clear();
72 | for (int i = 0; i < from.size(); i++){
73 | to.push();
74 | copy(from[i], to.last());
75 | }
76 | }
77 |
78 | template
79 | static inline void append(const vec& from, vec& to){ copy(from, to, true); }
80 |
81 | //=================================================================================================
82 | }
83 |
84 | #endif
85 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/Alloc.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************************[Alloc.h]
2 | Copyright (c) 2008-2010, Niklas Sorensson
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5 | associated documentation files (the "Software"), to deal in the Software without restriction,
6 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
7 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all copies or
11 | substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 | **************************************************************************************************/
19 |
20 |
21 | #ifndef Glucose_Alloc_h
22 | #define Glucose_Alloc_h
23 |
24 | #include "mtl/XAlloc.h"
25 | #include "mtl/Vec.h"
26 |
27 | namespace Glucose {
28 |
29 | //=================================================================================================
30 | // Simple Region-based memory allocator:
31 |
32 | template
33 | class RegionAllocator
34 | {
35 | T* memory;
36 | uint32_t sz;
37 | uint32_t cap;
38 | uint32_t wasted_;
39 |
40 | void capacity(uint32_t min_cap);
41 |
42 | public:
43 | // TODO: make this a class for better type-checking?
44 | typedef uint32_t Ref;
45 | enum { Ref_Undef = UINT32_MAX };
46 | enum { Unit_Size = sizeof(uint32_t) };
47 |
48 | explicit RegionAllocator(uint32_t start_cap = 1024*1024) : memory(NULL), sz(0), cap(0), wasted_(0){ capacity(start_cap); }
49 | ~RegionAllocator()
50 | {
51 | if (memory != NULL)
52 | ::free(memory);
53 | }
54 |
55 |
56 | uint32_t size () const { return sz; }
57 | uint32_t wasted () const { return wasted_; }
58 |
59 | Ref alloc (int size);
60 | void free (int size) { wasted_ += size; }
61 |
62 | // Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
63 | T& operator[](Ref r) { assert(r >= 0 && r < sz); return memory[r]; }
64 | const T& operator[](Ref r) const { assert(r >= 0 && r < sz); return memory[r]; }
65 |
66 | T* lea (Ref r) { assert(r >= 0 && r < sz); return &memory[r]; }
67 | const T* lea (Ref r) const { assert(r >= 0 && r < sz); return &memory[r]; }
68 | Ref ael (const T* t) { assert((void*)t >= (void*)&memory[0] && (void*)t < (void*)&memory[sz-1]);
69 | return (Ref)(t - &memory[0]); }
70 |
71 | void moveTo(RegionAllocator& to) {
72 | if (to.memory != NULL) ::free(to.memory);
73 | to.memory = memory;
74 | to.sz = sz;
75 | to.cap = cap;
76 | to.wasted_ = wasted_;
77 |
78 | memory = NULL;
79 | sz = cap = wasted_ = 0;
80 | }
81 |
82 |
83 | };
84 |
85 | template
86 | void RegionAllocator::capacity(uint32_t min_cap)
87 | {
88 | if (cap >= min_cap) return;
89 |
90 | uint32_t prev_cap = cap;
91 | while (cap < min_cap){
92 | // NOTE: Multiply by a factor (13/8) without causing overflow, then add 2 and make the
93 | // result even by clearing the least significant bit. The resulting sequence of capacities
94 | // is carefully chosen to hit a maximum capacity that is close to the '2^32-1' limit when
95 | // using 'uint32_t' as indices so that as much as possible of this space can be used.
96 | uint32_t delta = ((cap >> 1) + (cap >> 3) + 2) & ~1;
97 | cap += delta;
98 |
99 | if (cap <= prev_cap)
100 | throw OutOfMemoryException();
101 | }
102 | //printf(" .. (%p) cap = %u\n", this, cap);
103 |
104 | assert(cap > 0);
105 | memory = (T*)xrealloc(memory, sizeof(T)*cap);
106 | }
107 |
108 |
109 | template
110 | typename RegionAllocator::Ref
111 | RegionAllocator::alloc(int size)
112 | {
113 | //printf("ALLOC called (this = %p, size = %d)\n", this, size); fflush(stdout);
114 | assert(size > 0);
115 | capacity(sz + size);
116 |
117 | uint32_t prev_sz = sz;
118 | sz += size;
119 |
120 | // Handle overflow:
121 | if (sz < prev_sz)
122 | throw OutOfMemoryException();
123 |
124 | return prev_sz;
125 | }
126 |
127 |
128 | //=================================================================================================
129 | }
130 |
131 | #endif
132 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/Heap.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************************[Heap.h]
2 | Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3 | Copyright (c) 2007-2010, Niklas Sorensson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | associated documentation files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | **************************************************************************************************/
20 |
21 | #ifndef Glucose_Heap_h
22 | #define Glucose_Heap_h
23 |
24 | #include "mtl/Vec.h"
25 |
26 | namespace Glucose {
27 |
28 | //=================================================================================================
29 | // A heap implementation with support for decrease/increase key.
30 |
31 |
32 | template
33 | class Heap {
34 | Comp lt; // The heap is a minimum-heap with respect to this comparator
35 | vec heap; // Heap of integers
36 | vec indices; // Each integers position (index) in the Heap
37 |
38 | // Index "traversal" functions
39 | static inline int left (int i) { return i*2+1; }
40 | static inline int right (int i) { return (i+1)*2; }
41 | static inline int parent(int i) { return (i-1) >> 1; }
42 |
43 |
44 | void percolateUp(int i)
45 | {
46 | int x = heap[i];
47 | int p = parent(i);
48 |
49 | while (i != 0 && lt(x, heap[p])){
50 | heap[i] = heap[p];
51 | indices[heap[p]] = i;
52 | i = p;
53 | p = parent(p);
54 | }
55 | heap [i] = x;
56 | indices[x] = i;
57 | }
58 |
59 |
60 | void percolateDown(int i)
61 | {
62 | int x = heap[i];
63 | while (left(i) < heap.size()){
64 | int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
65 | if (!lt(heap[child], x)) break;
66 | heap[i] = heap[child];
67 | indices[heap[i]] = i;
68 | i = child;
69 | }
70 | heap [i] = x;
71 | indices[x] = i;
72 | }
73 |
74 |
75 | public:
76 | Heap(const Comp& c) : lt(c) { }
77 |
78 | int size () const { return heap.size(); }
79 | bool empty () const { return heap.size() == 0; }
80 | bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; }
81 | int operator[](int index) const { assert(index < heap.size()); return heap[index]; }
82 |
83 |
84 | void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); }
85 | void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
86 |
87 |
88 | // Safe variant of insert/decrease/increase:
89 | void update(int n)
90 | {
91 | if (!inHeap(n))
92 | insert(n);
93 | else {
94 | percolateUp(indices[n]);
95 | percolateDown(indices[n]); }
96 | }
97 |
98 |
99 | void insert(int n)
100 | {
101 | indices.growTo(n+1, -1);
102 | assert(!inHeap(n));
103 |
104 | indices[n] = heap.size();
105 | heap.push(n);
106 | percolateUp(indices[n]);
107 | }
108 |
109 |
110 | int removeMin()
111 | {
112 | int x = heap[0];
113 | heap[0] = heap.last();
114 | indices[heap[0]] = 0;
115 | indices[x] = -1;
116 | heap.pop();
117 | if (heap.size() > 1) percolateDown(0);
118 | return x;
119 | }
120 |
121 |
122 | // Rebuild the heap from scratch, using the elements in 'ns':
123 | void build(vec& ns) {
124 | for (int i = 0; i < heap.size(); i++)
125 | indices[heap[i]] = -1;
126 | heap.clear();
127 |
128 | for (int i = 0; i < ns.size(); i++){
129 | indices[ns[i]] = i;
130 | heap.push(ns[i]); }
131 |
132 | for (int i = heap.size() / 2 - 1; i >= 0; i--)
133 | percolateDown(i);
134 | }
135 |
136 | void clear(bool dealloc = false)
137 | {
138 | for (int i = 0; i < heap.size(); i++)
139 | indices[heap[i]] = -1;
140 | heap.clear(dealloc);
141 | }
142 | };
143 |
144 |
145 | //=================================================================================================
146 | }
147 |
148 | #endif
149 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/IntTypes.h:
--------------------------------------------------------------------------------
1 | /**************************************************************************************[IntTypes.h]
2 | Copyright (c) 2009-2010, Niklas Sorensson
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5 | associated documentation files (the "Software"), to deal in the Software without restriction,
6 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
7 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all copies or
11 | substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 | **************************************************************************************************/
19 |
20 | #ifndef Glucose_IntTypes_h
21 | #define Glucose_IntTypes_h
22 |
23 | #ifdef __sun
24 | // Not sure if there are newer versions that support C99 headers. The
25 | // needed features are implemented in the headers below though:
26 |
27 | # include
28 | # include
29 | # include
30 |
31 | #else
32 |
33 | # include
34 | # include
35 |
36 | #endif
37 |
38 | #include
39 |
40 | #ifndef PRIu64
41 | #define PRIu64 "lu"
42 | #define PRIi64 "ld"
43 | #endif
44 | //=================================================================================================
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/Map.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************************[Map.h]
2 | Copyright (c) 2006-2010, Niklas Sorensson
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5 | associated documentation files (the "Software"), to deal in the Software without restriction,
6 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
7 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all copies or
11 | substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 | **************************************************************************************************/
19 |
20 | #ifndef Glucose_Map_h
21 | #define Glucose_Map_h
22 |
23 | #include "mtl/IntTypes.h"
24 | #include "mtl/Vec.h"
25 |
26 | namespace Glucose {
27 |
28 | //=================================================================================================
29 | // Default hash/equals functions
30 | //
31 |
32 | template struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
33 | template struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
34 |
35 | template struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
36 | template struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
37 |
38 | static inline uint32_t hash(uint32_t x){ return x; }
39 | static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
40 | static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
41 | static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
42 |
43 |
44 | //=================================================================================================
45 | // Some primes
46 | //
47 |
48 | static const int nprimes = 25;
49 | static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 };
50 |
51 | //=================================================================================================
52 | // Hash table implementation of Maps
53 | //
54 |
55 | template, class E = Equal >
56 | class Map {
57 | public:
58 | struct Pair { K key; D data; };
59 |
60 | private:
61 | H hash;
62 | E equals;
63 |
64 | vec* table;
65 | int cap;
66 | int size;
67 |
68 | // Don't allow copying (error prone):
69 | Map& operator = (Map& other) { assert(0); }
70 | Map (Map& other) { assert(0); }
71 |
72 | bool checkCap(int new_size) const { return new_size > cap; }
73 |
74 | int32_t index (const K& k) const { return hash(k) % cap; }
75 | void _insert (const K& k, const D& d) {
76 | vec& ps = table[index(k)];
77 | ps.push(); ps.last().key = k; ps.last().data = d; }
78 |
79 | void rehash () {
80 | const vec* old = table;
81 |
82 | int old_cap = cap;
83 | int newsize = primes[0];
84 | for (int i = 1; newsize <= cap && i < nprimes; i++)
85 | newsize = primes[i];
86 |
87 | table = new vec[newsize];
88 | cap = newsize;
89 |
90 | for (int i = 0; i < old_cap; i++){
91 | for (int j = 0; j < old[i].size(); j++){
92 | _insert(old[i][j].key, old[i][j].data); }}
93 |
94 | delete [] old;
95 |
96 | // printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize);
97 | }
98 |
99 |
100 | public:
101 |
102 | Map () : table(NULL), cap(0), size(0) {}
103 | Map (const H& h, const E& e) : hash(h), equals(e), table(NULL), cap(0), size(0){}
104 | ~Map () { delete [] table; }
105 |
106 | // PRECONDITION: the key must already exist in the map.
107 | const D& operator [] (const K& k) const
108 | {
109 | assert(size != 0);
110 | const D* res = NULL;
111 | const vec& ps = table[index(k)];
112 | for (int i = 0; i < ps.size(); i++)
113 | if (equals(ps[i].key, k))
114 | res = &ps[i].data;
115 | assert(res != NULL);
116 | return *res;
117 | }
118 |
119 | // PRECONDITION: the key must already exist in the map.
120 | D& operator [] (const K& k)
121 | {
122 | assert(size != 0);
123 | D* res = NULL;
124 | vec& ps = table[index(k)];
125 | for (int i = 0; i < ps.size(); i++)
126 | if (equals(ps[i].key, k))
127 | res = &ps[i].data;
128 | assert(res != NULL);
129 | return *res;
130 | }
131 |
132 | // PRECONDITION: the key must *NOT* exist in the map.
133 | void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; }
134 | bool peek (const K& k, D& d) const {
135 | if (size == 0) return false;
136 | const vec& ps = table[index(k)];
137 | for (int i = 0; i < ps.size(); i++)
138 | if (equals(ps[i].key, k)){
139 | d = ps[i].data;
140 | return true; }
141 | return false;
142 | }
143 |
144 | bool has (const K& k) const {
145 | if (size == 0) return false;
146 | const vec& ps = table[index(k)];
147 | for (int i = 0; i < ps.size(); i++)
148 | if (equals(ps[i].key, k))
149 | return true;
150 | return false;
151 | }
152 |
153 | // PRECONDITION: the key must exist in the map.
154 | void remove(const K& k) {
155 | assert(table != NULL);
156 | vec& ps = table[index(k)];
157 | int j = 0;
158 | for (; j < ps.size() && !equals(ps[j].key, k); j++);
159 | assert(j < ps.size());
160 | ps[j] = ps.last();
161 | ps.pop();
162 | size--;
163 | }
164 |
165 | void clear () {
166 | cap = size = 0;
167 | delete [] table;
168 | table = NULL;
169 | }
170 |
171 | int elems() const { return size; }
172 | int bucket_count() const { return cap; }
173 |
174 | // NOTE: the hash and equality objects are not moved by this method:
175 | void moveTo(Map& other){
176 | delete [] other.table;
177 |
178 | other.table = table;
179 | other.cap = cap;
180 | other.size = size;
181 |
182 | table = NULL;
183 | size = cap = 0;
184 | }
185 |
186 | // NOTE: given a bit more time, I could make a more C++-style iterator out of this:
187 | const vec& bucket(int i) const { return table[i]; }
188 | };
189 |
190 | //=================================================================================================
191 | }
192 |
193 | #endif
194 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/Queue.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************************[Queue.h]
2 | Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3 | Copyright (c) 2007-2010, Niklas Sorensson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | associated documentation files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | **************************************************************************************************/
20 |
21 | #ifndef Glucose_Queue_h
22 | #define Glucose_Queue_h
23 |
24 | #include "mtl/Vec.h"
25 |
26 | namespace Glucose {
27 |
28 | //=================================================================================================
29 |
30 | template
31 | class Queue {
32 | vec buf;
33 | int first;
34 | int end;
35 |
36 | public:
37 | typedef T Key;
38 |
39 | Queue() : buf(1), first(0), end(0) {}
40 |
41 | void clear (bool dealloc = false) { buf.clear(dealloc); buf.growTo(1); first = end = 0; }
42 | int size () const { return (end >= first) ? end - first : end - first + buf.size(); }
43 |
44 | const T& operator [] (int index) const { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
45 | T& operator [] (int index) { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
46 |
47 | T peek () const { assert(first != end); return buf[first]; }
48 | void pop () { assert(first != end); first++; if (first == buf.size()) first = 0; }
49 | void insert(T elem) { // INVARIANT: buf[end] is always unused
50 | buf[end++] = elem;
51 | if (end == buf.size()) end = 0;
52 | if (first == end){ // Resize:
53 | vec tmp((buf.size()*3 + 1) >> 1);
54 | //**/printf("queue alloc: %d elems (%.1f MB)\n", tmp.size(), tmp.size() * sizeof(T) / 1000000.0);
55 | int i = 0;
56 | for (int j = first; j < buf.size(); j++) tmp[i++] = buf[j];
57 | for (int j = 0 ; j < end ; j++) tmp[i++] = buf[j];
58 | first = 0;
59 | end = buf.size();
60 | tmp.moveTo(buf);
61 | }
62 | }
63 | };
64 |
65 |
66 | //=================================================================================================
67 | }
68 |
69 | #endif
70 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/Sort.h:
--------------------------------------------------------------------------------
1 | /******************************************************************************************[Sort.h]
2 | Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
3 | Copyright (c) 2007-2010, Niklas Sorensson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | associated documentation files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | **************************************************************************************************/
20 |
21 | #ifndef Glucose_Sort_h
22 | #define Glucose_Sort_h
23 |
24 | #include "mtl/Vec.h"
25 |
26 | //=================================================================================================
27 | // Some sorting algorithms for vec's
28 |
29 |
30 | namespace Glucose {
31 |
32 | template
33 | struct LessThan_default {
34 | bool operator () (T x, T y) { return x < y; }
35 | };
36 |
37 |
38 | template
39 | void selectionSort(T* array, int size, LessThan lt)
40 | {
41 | int i, j, best_i;
42 | T tmp;
43 |
44 | for (i = 0; i < size-1; i++){
45 | best_i = i;
46 | for (j = i+1; j < size; j++){
47 | if (lt(array[j], array[best_i]))
48 | best_i = j;
49 | }
50 | tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
51 | }
52 | }
53 | template static inline void selectionSort(T* array, int size) {
54 | selectionSort(array, size, LessThan_default()); }
55 |
56 | template
57 | void sort(T* array, int size, LessThan lt)
58 | {
59 | if (size <= 15)
60 | selectionSort(array, size, lt);
61 |
62 | else{
63 | T pivot = array[size / 2];
64 | T tmp;
65 | int i = -1;
66 | int j = size;
67 |
68 | for(;;){
69 | do i++; while(lt(array[i], pivot));
70 | do j--; while(lt(pivot, array[j]));
71 |
72 | if (i >= j) break;
73 |
74 | tmp = array[i]; array[i] = array[j]; array[j] = tmp;
75 | }
76 |
77 | sort(array , i , lt);
78 | sort(&array[i], size-i, lt);
79 | }
80 | }
81 | template static inline void sort(T* array, int size) {
82 | sort(array, size, LessThan_default()); }
83 |
84 |
85 | //=================================================================================================
86 | // For 'vec's:
87 |
88 |
89 | template void sort(vec& v, LessThan lt) {
90 | sort((T*)v, v.size(), lt); }
91 | template void sort(vec& v) {
92 | sort(v, LessThan_default()); }
93 |
94 |
95 | //=================================================================================================
96 | }
97 |
98 | #endif
99 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/Vec.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************************[Vec.h]
2 | Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
3 | Copyright (c) 2007-2010, Niklas Sorensson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | associated documentation files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | **************************************************************************************************/
20 |
21 | #ifndef Glucose_Vec_h
22 | #define Glucose_Vec_h
23 |
24 | #include
25 | #include
26 |
27 | #include "mtl/IntTypes.h"
28 | #include "mtl/XAlloc.h"
29 |
30 | namespace Glucose {
31 |
32 | //=================================================================================================
33 | // Automatically resizable arrays
34 | //
35 | // NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
36 |
37 | template
38 | class vec {
39 | T* data;
40 | int sz;
41 | int cap;
42 |
43 | // Don't allow copying (error prone):
44 | vec& operator = (vec& other) { assert(0); return *this; }
45 | vec (vec& other) { assert(0); }
46 |
47 | // Helpers for calculating next capacity:
48 | static inline int imax (int x, int y) { int mask = (y-x) >> (sizeof(int)*8-1); return (x&mask) + (y&(~mask)); }
49 | //static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
50 | static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
51 |
52 | public:
53 | // Constructors:
54 | vec() : data(NULL) , sz(0) , cap(0) { }
55 | explicit vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); }
56 | vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); }
57 | ~vec() { clear(true); }
58 |
59 | // Pointer to first element:
60 | operator T* (void) { return data; }
61 |
62 | // Size operations:
63 | int size (void) const { return sz; }
64 | void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }
65 | void shrink_ (int nelems) { assert(nelems <= sz); sz -= nelems; }
66 | int capacity (void) const { return cap; }
67 | void capacity (int min_cap);
68 | void growTo (int size);
69 | void growTo (int size, const T& pad);
70 | void clear (bool dealloc = false);
71 |
72 | // Stack interface:
73 | void push (void) { if (sz == cap) capacity(sz+1); new (&data[sz]) T(); sz++; }
74 | void push (const T& elem) { if (sz == cap) capacity(sz+1); data[sz++] = elem; }
75 | void push_ (const T& elem) { assert(sz < cap); data[sz++] = elem; }
76 | void pop (void) { assert(sz > 0); sz--, data[sz].~T(); }
77 | // NOTE: it seems possible that overflow can happen in the 'sz+1' expression of 'push()', but
78 | // in fact it can not since it requires that 'cap' is equal to INT_MAX. This in turn can not
79 | // happen given the way capacities are calculated (below). Essentially, all capacities are
80 | // even, but INT_MAX is odd.
81 |
82 | const T& last (void) const { return data[sz-1]; }
83 | T& last (void) { return data[sz-1]; }
84 |
85 | // Vector interface:
86 | const T& operator [] (int index) const { return data[index]; }
87 | T& operator [] (int index) { return data[index]; }
88 |
89 | // Duplicatation (preferred instead):
90 | void copyTo(vec& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
91 | void moveTo(vec& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
92 | };
93 |
94 |
95 | template
96 | void vec::capacity(int min_cap) {
97 | if (cap >= min_cap) return;
98 | int add = imax((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1); // NOTE: grow by approximately 3/2
99 | if (add > INT_MAX - cap || ((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM)
100 | throw OutOfMemoryException();
101 | }
102 |
103 |
104 | template
105 | void vec::growTo(int size, const T& pad) {
106 | if (sz >= size) return;
107 | capacity(size);
108 | for (int i = sz; i < size; i++) data[i] = pad;
109 | sz = size; }
110 |
111 |
112 | template
113 | void vec::growTo(int size) {
114 | if (sz >= size) return;
115 | capacity(size);
116 | for (int i = sz; i < size; i++) new (&data[i]) T();
117 | sz = size; }
118 |
119 |
120 | template
121 | void vec::clear(bool dealloc) {
122 | if (data != NULL){
123 | for (int i = 0; i < sz; i++) data[i].~T();
124 | sz = 0;
125 | if (dealloc) free(data), data = NULL, cap = 0; } }
126 |
127 | //=================================================================================================
128 | }
129 |
130 | #endif
131 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/XAlloc.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************************[XAlloc.h]
2 | Copyright (c) 2009-2010, Niklas Sorensson
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5 | associated documentation files (the "Software"), to deal in the Software without restriction,
6 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
7 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all copies or
11 | substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 | **************************************************************************************************/
19 |
20 |
21 | #ifndef Glucose_XAlloc_h
22 | #define Glucose_XAlloc_h
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | namespace Glucose {
29 |
30 | //=================================================================================================
31 | // Simple layer on top of malloc/realloc to catch out-of-memory situtaions and provide some typing:
32 |
33 | class OutOfMemoryException{};
34 | static inline void* xrealloc(void *ptr, size_t size)
35 | {
36 | void* mem = realloc(ptr, size);
37 | if (mem == NULL && errno == ENOMEM){
38 | throw OutOfMemoryException();
39 | }else {
40 | return mem;
41 | }
42 | }
43 |
44 | //=================================================================================================
45 | }
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/config.mk:
--------------------------------------------------------------------------------
1 | ##
2 | ## This file is for system specific configurations. For instance, on
3 | ## some systems the path to zlib needs to be added. Example:
4 | ##
5 | ## CFLAGS += -I/usr/local/include
6 | ## LFLAGS += -L/usr/local/lib
7 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/mtl/template.mk:
--------------------------------------------------------------------------------
1 | ##
2 | ## Template makefile for Standard, Profile, Debug, Release, and Release-static versions
3 | ##
4 | ## eg: "make rs" for a statically linked release version.
5 | ## "make d" for a debug version (no optimizations).
6 | ## "make" for the standard version (optimized, but with debug information and assertions active)
7 |
8 | PWD = $(shell pwd)
9 | EXEC ?= $(notdir $(PWD))
10 |
11 | CSRCS = $(wildcard $(PWD)/*.cc)
12 | DSRCS = $(foreach dir, $(DEPDIR), $(filter-out $(MROOT)/$(dir)/Main.cc, $(wildcard $(MROOT)/$(dir)/*.cc)))
13 | CHDRS = $(wildcard $(PWD)/*.h)
14 | COBJS = $(CSRCS:.cc=.o) $(DSRCS:.cc=.o)
15 |
16 | PCOBJS = $(addsuffix p, $(COBJS))
17 | DCOBJS = $(addsuffix d, $(COBJS))
18 | RCOBJS = $(addsuffix r, $(COBJS))
19 |
20 | CXX ?= g++ # may need g++ version 4.4 or higher
21 | CFLAGS ?= -Wall -Wno-parentheses
22 | LFLAGS ?= -Wall
23 |
24 | COPTIMIZE ?= -O3
25 |
26 | CFLAGS += -I$(MROOT) -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS
27 | LFLAGS += -lz
28 |
29 | .PHONY : s p d r rs clean
30 |
31 | s: $(EXEC)
32 | p: $(EXEC)_profile
33 | d: $(EXEC)_debug
34 | r: $(EXEC)_release
35 | rs: $(EXEC)_static
36 |
37 | libs: lib$(LIB)_standard.a
38 | libp: lib$(LIB)_profile.a
39 | libd: lib$(LIB)_debug.a
40 | libr: lib$(LIB)_release.a
41 |
42 | ## Compile options
43 | %.o: CFLAGS +=$(COPTIMIZE) -g -D DEBUG
44 | %.op: CFLAGS +=$(COPTIMIZE) -pg -g -D NDEBUG
45 | %.od: CFLAGS +=-O0 -g -D DEBUG
46 | %.or: CFLAGS +=$(COPTIMIZE) -g -D NDEBUG
47 |
48 | ## Link options
49 | $(EXEC): LFLAGS += -g
50 | $(EXEC)_profile: LFLAGS += -g -pg
51 | $(EXEC)_debug: LFLAGS += -g
52 | #$(EXEC)_release: LFLAGS += ...
53 | #$(EXEC)_static: LFLAGS += --static
54 | $(EXEC)_static: LFLAGS += -static-libgcc -static-libstdc++
55 |
56 | ## Dependencies
57 | $(EXEC): $(COBJS)
58 | $(EXEC)_profile: $(PCOBJS)
59 | $(EXEC)_debug: $(DCOBJS)
60 | $(EXEC)_release: $(RCOBJS)
61 | $(EXEC)_static: $(RCOBJS)
62 |
63 | lib$(LIB)_standard.a: $(filter-out */Main.o, $(COBJS))
64 | lib$(LIB)_profile.a: $(filter-out */Main.op, $(PCOBJS))
65 | lib$(LIB)_debug.a: $(filter-out */Main.od, $(DCOBJS))
66 | lib$(LIB)_release.a: $(filter-out */Main.or, $(RCOBJS))
67 |
68 |
69 | ## Build rule
70 | %.o %.op %.od %.or: %.cc
71 | @echo Compiling: $(subst $(MROOT)/,,$@)
72 | @$(CXX) $(CFLAGS) -c -o $@ $<
73 |
74 | ## Linking rules (standard/profile/debug/release)
75 | $(EXEC) $(EXEC)_profile $(EXEC)_debug $(EXEC)_release $(EXEC)_static:
76 | @echo Linking: "$@ ( $(foreach f,$^,$(subst $(MROOT)/,,$f)) )"
77 | @$(CXX) $^ $(LFLAGS) -o $@
78 |
79 | ## Library rules (standard/profile/debug/release)
80 | lib$(LIB)_standard.a lib$(LIB)_profile.a lib$(LIB)_release.a lib$(LIB)_debug.a:
81 | @echo Making library: "$@ ( $(foreach f,$^,$(subst $(MROOT)/,,$f)) )"
82 | @$(AR) -rcsv $@ $^
83 |
84 | ## Library Soft Link rule:
85 | libs libp libd libr:
86 | @echo "Making Soft Link: $^ -> lib$(LIB).a"
87 | @ln -sf $^ lib$(LIB).a
88 |
89 | ## Clean rule
90 | clean:
91 | @rm -f $(EXEC) $(EXEC)_profile $(EXEC)_debug $(EXEC)_release $(EXEC)_static \
92 | $(COBJS) $(PCOBJS) $(DCOBJS) $(RCOBJS) *.core depend.mk
93 |
94 | ## Make dependencies
95 | depend.mk: $(CSRCS) $(CHDRS)
96 | @echo Making dependencies
97 | @$(CXX) $(CFLAGS) -I$(MROOT) \
98 | $(CSRCS) -MM | sed 's|\(.*\):|$(PWD)/\1 $(PWD)/\1r $(PWD)/\1d $(PWD)/\1p:|' > depend.mk
99 | @for dir in $(DEPDIR); do \
100 | if [ -r $(MROOT)/$${dir}/depend.mk ]; then \
101 | echo Depends on: $${dir}; \
102 | cat $(MROOT)/$${dir}/depend.mk >> depend.mk; \
103 | fi; \
104 | done
105 |
106 | -include $(MROOT)/mtl/config.mk
107 | -include depend.mk
108 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/utils/Makefile:
--------------------------------------------------------------------------------
1 | EXEC = system_test
2 | DEPDIR = mtl
3 |
4 | include $(MROOT)/mtl/template.mk
5 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/utils/Options.cc:
--------------------------------------------------------------------------------
1 | /**************************************************************************************[Options.cc]
2 | Copyright (c) 2008-2010, Niklas Sorensson
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5 | associated documentation files (the "Software"), to deal in the Software without restriction,
6 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
7 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all copies or
11 | substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 | **************************************************************************************************/
19 |
20 | #include "mtl/Sort.h"
21 | #include "utils/Options.h"
22 | #include "utils/ParseUtils.h"
23 |
24 | using namespace Glucose;
25 |
26 | void Glucose::parseOptions(int& argc, char** argv, bool strict)
27 | {
28 | int i, j;
29 | for (i = j = 1; i < argc; i++){
30 | const char* str = argv[i];
31 | if (match(str, "--") && match(str, Option::getHelpPrefixString()) && match(str, "help")){
32 | if (*str == '\0')
33 | printUsageAndExit(argc, argv);
34 | else if (match(str, "-verb"))
35 | printUsageAndExit(argc, argv, true);
36 | } else {
37 | bool parsed_ok = false;
38 |
39 | for (int k = 0; !parsed_ok && k < Option::getOptionList().size(); k++){
40 | parsed_ok = Option::getOptionList()[k]->parse(argv[i]);
41 |
42 | // fprintf(stderr, "checking %d: %s against flag <%s> (%s)\n", i, argv[i], Option::getOptionList()[k]->name, parsed_ok ? "ok" : "skip");
43 | }
44 |
45 | if (!parsed_ok)
46 | if (strict && match(argv[i], "-"))
47 | fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()), exit(1);
48 | else
49 | argv[j++] = argv[i];
50 | }
51 | }
52 |
53 | argc -= (i - j);
54 | }
55 |
56 |
57 | void Glucose::setUsageHelp (const char* str){ Option::getUsageString() = str; }
58 | void Glucose::setHelpPrefixStr (const char* str){ Option::getHelpPrefixString() = str; }
59 | void Glucose::printUsageAndExit (int argc, char** argv, bool verbose)
60 | {
61 | const char* usage = Option::getUsageString();
62 | if (usage != NULL)
63 | fprintf(stderr, usage, argv[0]);
64 |
65 | sort(Option::getOptionList(), Option::OptionLt());
66 |
67 | const char* prev_cat = NULL;
68 | const char* prev_type = NULL;
69 |
70 | for (int i = 0; i < Option::getOptionList().size(); i++){
71 | const char* cat = Option::getOptionList()[i]->category;
72 | const char* type = Option::getOptionList()[i]->type_name;
73 |
74 | if (cat != prev_cat)
75 | fprintf(stderr, "\n%s OPTIONS:\n\n", cat);
76 | else if (type != prev_type)
77 | fprintf(stderr, "\n");
78 |
79 | Option::getOptionList()[i]->help(verbose);
80 |
81 | prev_cat = Option::getOptionList()[i]->category;
82 | prev_type = Option::getOptionList()[i]->type_name;
83 | }
84 |
85 | fprintf(stderr, "\nHELP OPTIONS:\n\n");
86 | fprintf(stderr, " --%shelp Print help message.\n", Option::getHelpPrefixString());
87 | fprintf(stderr, " --%shelp-verb Print verbose help message.\n", Option::getHelpPrefixString());
88 | fprintf(stderr, "\n");
89 | exit(0);
90 | }
91 |
92 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/utils/ParseUtils.h:
--------------------------------------------------------------------------------
1 | /************************************************************************************[ParseUtils.h]
2 | Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3 | Copyright (c) 2007-2010, Niklas Sorensson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | associated documentation files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | **************************************************************************************************/
20 |
21 | #ifndef Glucose_ParseUtils_h
22 | #define Glucose_ParseUtils_h
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | #include
29 |
30 | namespace Glucose {
31 |
32 | //-------------------------------------------------------------------------------------------------
33 | // A simple buffered character stream class:
34 |
35 | static const int buffer_size = 1048576;
36 |
37 |
38 | class StreamBuffer {
39 | gzFile in;
40 | unsigned char buf[buffer_size];
41 | int pos;
42 | int size;
43 |
44 | void assureLookahead() {
45 | if (pos >= size) {
46 | pos = 0;
47 | size = gzread(in, buf, sizeof(buf)); } }
48 |
49 | public:
50 | explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0) { assureLookahead(); }
51 |
52 | int operator * () const { return (pos >= size) ? EOF : buf[pos]; }
53 | void operator ++ () { pos++; assureLookahead(); }
54 | int position () const { return pos; }
55 | };
56 |
57 |
58 | //-------------------------------------------------------------------------------------------------
59 | // End-of-file detection functions for StreamBuffer and char*:
60 |
61 |
62 | static inline bool isEof(StreamBuffer& in) { return *in == EOF; }
63 | static inline bool isEof(const char* in) { return *in == '\0'; }
64 |
65 | //-------------------------------------------------------------------------------------------------
66 | // Generic parse functions parametrized over the input-stream type.
67 |
68 |
69 | template
70 | static void skipWhitespace(B& in) {
71 | while ((*in >= 9 && *in <= 13) || *in == 32)
72 | ++in; }
73 |
74 |
75 | template
76 | static void skipLine(B& in) {
77 | for (;;){
78 | if (isEof(in)) return;
79 | if (*in == '\n') { ++in; return; }
80 | ++in; } }
81 |
82 | template
83 | static double parseDouble(B& in) { // only in the form X.XXXXXe-XX
84 | bool neg= false;
85 | double accu = 0.0;
86 | double currentExponent = 1;
87 | int exponent;
88 |
89 | skipWhitespace(in);
90 | if(*in == EOF) return 0;
91 | if (*in == '-') neg = true, ++in;
92 | else if (*in == '+') ++in;
93 | if (*in < '1' || *in > '9') printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
94 | accu = (double)(*in - '0');
95 | ++in;
96 | if (*in != '.') printf("PARSE ERROR! Unexpected char: %c\n", *in),exit(3);
97 | ++in; // skip dot
98 | currentExponent = 0.1;
99 | while (*in >= '0' && *in <= '9')
100 | accu = accu + currentExponent * ((double)(*in - '0')),
101 | currentExponent /= 10,
102 | ++in;
103 | if (*in != 'e') printf("PARSE ERROR! Unexpected char: %c\n", *in),exit(3);
104 | ++in; // skip dot
105 | exponent = parseInt(in); // read exponent
106 | accu *= pow(10,exponent);
107 | return neg ? -accu:accu;
108 | }
109 |
110 |
111 | template
112 | static int parseInt(B& in) {
113 | int val = 0;
114 | bool neg = false;
115 | skipWhitespace(in);
116 | if (*in == '-') neg = true, ++in;
117 | else if (*in == '+') ++in;
118 | if (*in < '0' || *in > '9') fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
119 | while (*in >= '0' && *in <= '9')
120 | val = val*10 + (*in - '0'),
121 | ++in;
122 | return neg ? -val : val; }
123 |
124 |
125 | // String matching: in case of a match the input iterator will be advanced the corresponding
126 | // number of characters.
127 | template
128 | static bool match(B& in, const char* str) {
129 | int i;
130 | for (i = 0; str[i] != '\0'; i++)
131 | if (in[i] != str[i])
132 | return false;
133 |
134 | in += i;
135 |
136 | return true;
137 | }
138 |
139 | // String matching: consumes characters eagerly, but does not require random access iterator.
140 | template
141 | static bool eagerMatch(B& in, const char* str) {
142 | for (; *str != '\0'; ++str, ++in)
143 | if (*str != *in)
144 | return false;
145 | return true; }
146 |
147 |
148 | //=================================================================================================
149 | }
150 |
151 | #endif
152 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/utils/System.cc:
--------------------------------------------------------------------------------
1 | /***************************************************************************************[System.cc]
2 | Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3 | Copyright (c) 2007-2010, Niklas Sorensson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | associated documentation files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | **************************************************************************************************/
20 |
21 | #include "utils/System.h"
22 |
23 | #if defined(__linux__)
24 |
25 | #include
26 | #include
27 |
28 | using namespace Glucose;
29 |
30 | // TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and
31 | // one for reading the current virtual memory size.
32 |
33 | static inline int memReadStat(int field)
34 | {
35 | char name[256];
36 | pid_t pid = getpid();
37 | int value;
38 |
39 | sprintf(name, "/proc/%d/statm", pid);
40 | FILE* in = fopen(name, "rb");
41 | if (in == NULL) return 0;
42 |
43 | for (; field >= 0; field--)
44 | if (fscanf(in, "%d", &value) != 1)
45 | printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1);
46 | fclose(in);
47 | return value;
48 | }
49 |
50 |
51 | static inline int memReadPeak(void)
52 | {
53 | char name[256];
54 | pid_t pid = getpid();
55 |
56 | sprintf(name, "/proc/%d/status", pid);
57 | FILE* in = fopen(name, "rb");
58 | if (in == NULL) return 0;
59 |
60 | // Find the correct line, beginning with "VmPeak:":
61 | int peak_kb = 0;
62 | while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1)
63 | while (!feof(in) && fgetc(in) != '\n')
64 | ;
65 | fclose(in);
66 |
67 | return peak_kb;
68 | }
69 |
70 | double Glucose::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); }
71 | double Glucose::memUsedPeak() {
72 | double peak = memReadPeak() / 1024;
73 | return peak == 0 ? memUsed() : peak; }
74 |
75 | #elif defined(__FreeBSD__)
76 |
77 | double Glucose::memUsed(void) {
78 | struct rusage ru;
79 | getrusage(RUSAGE_SELF, &ru);
80 | return (double)ru.ru_maxrss / 1024; }
81 | double MiniSat::memUsedPeak(void) { return memUsed(); }
82 |
83 |
84 | #elif defined(__APPLE__)
85 | #include
86 |
87 | double Glucose::memUsed(void) {
88 | malloc_statistics_t t;
89 | malloc_zone_statistics(NULL, &t);
90 | return (double)t.max_size_in_use / (1024*1024); }
91 |
92 | #else
93 | double Glucose::memUsed() {
94 | return 0; }
95 | #endif
96 |
--------------------------------------------------------------------------------
/src/glucose-30-backbone/utils/System.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************************[System.h]
2 | Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3 | Copyright (c) 2007-2010, Niklas Sorensson
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 | associated documentation files (the "Software"), to deal in the Software without restriction,
7 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or
12 | substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18 | OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 | **************************************************************************************************/
20 |
21 | #ifndef Glucose_System_h
22 | #define Glucose_System_h
23 |
24 | #if defined(__linux__)
25 | #include
26 | #endif
27 |
28 | #include "mtl/IntTypes.h"
29 |
30 | //-------------------------------------------------------------------------------------------------
31 |
32 | namespace Glucose {
33 |
34 | static inline double cpuTime(void); // CPU-time in seconds.
35 | extern double memUsed(); // Memory in mega bytes (returns 0 for unsupported architectures).
36 | extern double memUsedPeak(); // Peak-memory in mega bytes (returns 0 for unsupported architectures).
37 |
38 | }
39 |
40 | //-------------------------------------------------------------------------------------------------
41 | // Implementation of inline functions:
42 |
43 | #if defined(_MSC_VER) || defined(__MINGW32__)
44 | #include
45 |
46 | static inline double Glucose::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; }
47 |
48 | #else
49 | #include
50 | #include
51 | #include
52 |
53 | static inline double Glucose::cpuTime(void) {
54 | struct rusage ru;
55 | getrusage(RUSAGE_SELF, &ru);
56 | return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
57 |
58 | #endif
59 |
60 | #endif
61 |
--------------------------------------------------------------------------------
/src/main/java/tuffy/db/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | package
4 |
5 |
6 | Provides interfaces to the RDBMS. Currently only supports PostgreSQL.
7 |
8 |
--------------------------------------------------------------------------------
/src/main/java/tuffy/ground/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | package
4 |
5 |
6 | Provides facilities for grounding MLNs, including KBMC, SQL-based grounding, and MRF partitioning.
7 |
8 |
9 | Grounding will be conducted in three phases:
10 |
11 | - Ground relevant atoms: This phase is done by class KBMC. In this phase, a rough sift
12 | of atoms results from a partially grounded predicate tables. In these tables (one
13 | for each predicate), those definitely not useful atoms are not grounded.
14 |
- Pick active atoms: This phase is done by class Grounding. In this phase, all
15 | atoms that will not violate any clauses by default are further eliminated
16 | on the basis of the first phase. These eliminated atoms will not play any role
17 | in following inference or learning, therefore grounding them out will make no sense.
18 |
- Ground active clauses: This phase is done by class Grounding. In this phase, clauses
19 | are grounded according to picked active atoms in the second phase. Clauses relying on
20 | exactly the same atoms will be merged together to form GClause for efficiency
21 | consideration.
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/main/java/tuffy/ground/package_grounding.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/allenai/tuffylite/932ab8448c15e90bbcca87f6b3d20a2dbc7076b1/src/main/java/tuffy/ground/package_grounding.jpeg
--------------------------------------------------------------------------------
/src/main/java/tuffy/ground/partition/Component.java:
--------------------------------------------------------------------------------
1 | package tuffy.ground.partition;
2 |
3 |
4 | import java.util.ArrayList;
5 | import java.util.LinkedHashMap;
6 | import java.util.LinkedHashSet;
7 |
8 | import tuffy.infer.ds.GAtom;
9 | import tuffy.util.UIMan;
10 | /**
11 | * A component in the MRF.
12 | */
13 |
14 | public class Component implements Comparable{
15 | public int id = 0;
16 | public int rep = 0; // representative atom id
17 | public int numAtoms = 0;
18 | public int numClauses = 0;
19 | public int numCutClauses = 0;
20 | public int numPins = 0;
21 | public double totalWeight = 0;
22 | public double totalCutWeight = 0;
23 | public double ramSize = 0;
24 | public boolean hasQueryAtom = false;
25 |
26 | // partitions in this component; maybe only one
27 | public ArrayList parts = new ArrayList();
28 | // atoms that are at the boundary
29 | public LinkedHashSet cutset = new LinkedHashSet();
30 |
31 | // aid --> atom
32 | public LinkedHashMap atoms;
33 |
34 |
35 | /**
36 | * Add a new atom into this component.
37 | * @param a the atom
38 | */
39 | public void addAtom(GAtom a){
40 | atoms.put(a.id, a);
41 | }
42 |
43 | /**
44 | * Discard all data structures to reclaim the RAM.
45 | */
46 | public void discard(){
47 | cutset.clear();
48 | if(atoms != null){
49 | atoms.clear();
50 | }
51 | atoms = null;
52 | for(Partition p : parts){
53 | p.discard();
54 | }
55 | }
56 |
57 | /**
58 | * Show basic stats of this component.
59 | */
60 | public void showStats(){
61 | String s = "[Component #" + id + "]" +
62 | "\n\tRAM = " + ramSize + " bytes" +
63 | "\n\t#parts = " + parts.size() +
64 | "\n\t#atoms = " + numAtoms +
65 | "\n\t#clauses = " + numClauses +
66 | "\n\t#cut_atoms = " + cutset.size();
67 | UIMan.println(s);
68 | }
69 |
70 | public int compareTo(Component c){
71 | double d = c.size() - size();
72 | return (int)(Math.signum(d));
73 | }
74 |
75 | /**
76 | * The size of this component estimated in
77 | * the number fo bytes consumed to store this component in RAM.
78 | */
79 | public double size(){
80 | return ramSize;
81 | }
82 |
83 | /**
84 | * Get the number of partitions in this component.
85 | */
86 | public int numParts(){
87 | return parts.size();
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/tuffy/ground/partition/Partition.java:
--------------------------------------------------------------------------------
1 | package tuffy.ground.partition;
2 |
3 | import java.util.ArrayList;
4 |
5 | import tuffy.infer.MRF;
6 | import tuffy.util.BitSetIntPair;
7 | import tuffy.util.UIMan;
8 |
9 | /**
10 | * A partition is a subgraph of an MRF component.
11 | */
12 | public class Partition implements Comparable{
13 | public int id; // ID of this partition
14 | public int numAtoms = 0;
15 | public int numIncidentClauses = 0;
16 | public double ramSize = 0;
17 |
18 | public Component parentComponent = null;
19 |
20 | public MRF mrf = null;
21 |
22 | public ArrayList mle_freq_cache = new ArrayList();
23 |
24 |
25 | public int compareTo(Partition c){
26 | double d = c.size() - size();
27 | return (int)(Math.signum(d));
28 | }
29 |
30 | /**
31 | * Get the estimated RAM size of this partition.
32 | */
33 | public double size(){
34 | return ramSize;
35 | }
36 |
37 | /**
38 | * Discard all data structures to facilitate GC. (Does it really work?)
39 | */
40 | public void discard() {
41 | if(mrf != null) mrf.discard();
42 | mrf = null;
43 | }
44 |
45 |
46 | /**
47 | * Show basic stats about this partition.
48 | */
49 | public void showStats(){
50 | String s = "[Partition #" + id + "]" +
51 | "\tRAM = " + ramSize +
52 | "\t#atoms = " + numAtoms +
53 | "\t#incident_clauses = " + numIncidentClauses;
54 | if(mrf != null){
55 | s += "\t#core_atoms = " + mrf.getCoreAtoms().size();
56 | s += "\t#core_clauses = " + mrf.clauses.size();
57 | }
58 | UIMan.println(s);
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/tuffy/ground/partition/PartitionScheme.java:
--------------------------------------------------------------------------------
1 | package tuffy.ground.partition;
2 |
3 |
4 | import java.util.ArrayList;
5 | import java.util.LinkedHashMap;
6 |
7 | import tuffy.infer.MRF;
8 | import tuffy.util.StringMan;
9 | /**
10 | * A partitioning scheme on an MRF. Such a scheme consists of one or more components, with
11 | * each component consisting of one or more partitions. Components are disjoint from each other,
12 | * whereas partitions within the same component may share hyper-edges (i.e., clauses).
13 | * In the current policy, each hyper-edge being shared across partitioned is randomly
14 | * assigned to only one of the adjacent partitions.
15 | *
16 | */
17 | public class PartitionScheme {
18 | /**
19 | * Components and partitions.
20 | * Each component or partition has a unique ID.
21 | */
22 | public ArrayList components = new ArrayList();
23 | private LinkedHashMap compMap = new LinkedHashMap();
24 | private LinkedHashMap partMap = new LinkedHashMap();
25 |
26 | /**
27 | * Stats.
28 | */
29 | private int ncomp = 0;
30 | private int npart = 0;
31 | public double totalSize = 0, maxCompSize = 0, maxPartSize = 0,
32 | maxNumAtomsInComp = 0, maxNumAtomsInPart = 0;
33 | private long numAtoms = 0, numClauses = 0, numCutClauses = 0;
34 | private int numSplitComps = 0, maxSplitFactor = 1;
35 |
36 |
37 | /**
38 | * Show stats about this partitioning scheme.
39 | */
40 | public String getStats(){
41 | ArrayList lines = new ArrayList();
42 | lines.add("------BEGIN: PARTITION STATS------");
43 | lines.add("#atoms = " + numAtoms);
44 | lines.add("#clauses = " + numClauses);
45 | lines.add("#components = " + ncomp);
46 | lines.add("#partitions = " + npart);
47 |
48 | lines.add("#max_comp_size = " + maxCompSize);
49 | lines.add("#max_part_size = " + maxPartSize);
50 | lines.add("#split_component = " + numSplitComps);
51 | lines.add("#max_num_atoms_in_comp = " + maxNumAtomsInComp);
52 | lines.add("#max_num_atoms_in_part = " + maxNumAtomsInPart);
53 | lines.add("#max_partitions_in_one_comp = " + maxSplitFactor);
54 | lines.add("#cut_clauses = " + numCutClauses);
55 |
56 | lines.add("------ END: PARTITION STATS-------");
57 | return StringMan.join("\n", lines);
58 | }
59 |
60 | public long getNumAtoms(){
61 | return numAtoms;
62 | }
63 |
64 | public Component getCompByID(int id){
65 | return compMap.get(id);
66 | }
67 |
68 | public Component getCompByPartID(int pid){
69 | return partMap.get(pid).parentComponent;
70 | }
71 |
72 | public Partition getPartitionByID(int pid){
73 | return partMap.get(pid);
74 | }
75 |
76 | public MRF getMRFByPartID(int pid){
77 | return partMap.get(pid).mrf;
78 | }
79 |
80 | public PartitionScheme(ArrayList comps){
81 | components = comps;
82 | ncomp = comps.size();
83 | npart = 0;
84 | for(Component c : comps){
85 | npart += c.numParts();
86 | totalSize += c.size();
87 | numAtoms += c.numAtoms;
88 | numClauses += c.numClauses;
89 | numCutClauses += c.numCutClauses;
90 | if(c.size() > maxCompSize){
91 | maxCompSize = c.size();
92 | }
93 | if(c.numAtoms > maxNumAtomsInComp){
94 | maxNumAtomsInComp = c.numAtoms;
95 | }
96 | if(c.parts.size() > 1){
97 | numSplitComps++;
98 | if(c.parts.size() > maxSplitFactor){
99 | maxSplitFactor = c.parts.size();
100 | }
101 | }
102 | compMap.put(c.id, c);
103 | for(Partition p : c.parts){
104 | partMap.put(p.id, p);
105 | if(p.numAtoms > maxNumAtomsInPart){
106 | maxNumAtomsInPart = p.numAtoms;
107 | }
108 | if(p.size() > maxPartSize){
109 | maxPartSize = p.size();
110 | }
111 | }
112 | }
113 | }
114 |
115 | /**
116 | * Estimated RAM size required to hold everything.
117 | */
118 | public double size(){
119 | return totalSize;
120 | }
121 |
122 | public int numComponents(){
123 | return ncomp;
124 | }
125 |
126 | public int numParts(){
127 | return npart;
128 | }
129 |
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/src/main/java/tuffy/ground/partition/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | package
4 |
5 |
6 | Data structures and algorithms for MRF partitioning.
7 |
8 |
--------------------------------------------------------------------------------
/src/main/java/tuffy/helper/Stats.java:
--------------------------------------------------------------------------------
1 | package tuffy.helper;
2 |
3 |
4 | import java.sql.ResultSet;
5 | import java.sql.SQLException;
6 | import java.util.ArrayList;
7 | import java.util.Comparator;
8 | import java.util.LinkedHashMap;
9 | import java.util.PriorityQueue;
10 |
11 | import tuffy.db.RDB;
12 | import tuffy.infer.MRF;
13 | import tuffy.infer.ds.GAtom;
14 | import tuffy.infer.ds.GClause;
15 | import tuffy.mln.Clause;
16 | import tuffy.mln.MarkovLogicNetwork;
17 | import tuffy.mln.Predicate;
18 | import tuffy.util.Config;
19 | import tuffy.util.ExceptionMan;
20 | import tuffy.util.FileMan;
21 | import tuffy.util.StringMan;
22 | import tuffy.util.UIMan;
23 | /**
24 | * Stats collected from inference. Mainly for debugging and MLN developping purposes.
25 | * Current implementation/features are very rough.
26 | */
27 | public class Stats {
28 |
29 | public static class ClauseCostComparator implements Comparator
30 | {
31 | @Override
32 | public int compare(Clause x, Clause y)
33 | {
34 | double d = x.cost - y.cost;
35 | if(d > 0){
36 | return -1;
37 | }
38 | if(d < 0){
39 | return 1;
40 | }
41 | return 0;
42 | }
43 | }
44 |
45 | public static void dumpStats(MRF mrf){
46 | StringBuilder sb = new StringBuilder();
47 | sb.append(reportMostViolatedClauses(mrf, 100));
48 | UIMan.println(">>> Writing stats to " + Config.file_stats + "...");
49 | FileMan.writeToFile(Config.file_stats, sb.toString());
50 | }
51 |
52 | public static void pullAtomReps(MRF mrf){
53 | MarkovLogicNetwork mln = mrf.getMLN();
54 | LinkedHashMap atoms = mrf.atoms;
55 | RDB db = mln.getRDB();
56 | LinkedHashMap cmap = db.loadIdSymbolMapFromTable();
57 | for(Predicate p : mln.getAllPred()) {
58 | if(p.isImmutable()) continue;
59 | String sql = "SELECT * FROM " + p.getRelName() +
60 | " WHERE id >= 0";
61 | ResultSet rs = db.query(sql);
62 | try {
63 | while(rs.next()) {
64 | int aid = rs.getInt("id");
65 | GAtom a = atoms.get(aid);
66 | if(a == null) continue;
67 | StringBuilder line = new StringBuilder();
68 | line.append(p.getName() + "(");
69 | ArrayList cs = new ArrayList();
70 | for(String arg : p.getArgs()) {
71 | long c = rs.getLong(arg);
72 | cs.add(cmap.get(c));
73 | }
74 | line.append(StringMan.commaList(cs) + ")");
75 | a.rep = line.toString();
76 | }
77 | rs.close();
78 | } catch (SQLException e) {
79 | ExceptionMan.handle(e);
80 | }
81 | }
82 | }
83 |
84 | public static String reportMostViolatedClauses(MRF mrf, int k){
85 | if(mrf.getCost() <= 0) return "/* There were no clauses violated */\n";
86 | mrf.auditClauseViolations();
87 | MarkovLogicNetwork mln = mrf.getMLN();
88 | pullAtomReps(mrf);
89 | ClauseCostComparator comp = new ClauseCostComparator();
90 | PriorityQueue pq = new PriorityQueue(k, comp);
91 | pq.addAll(mln.getAllNormalizedClauses());
92 | StringBuilder sbh = new StringBuilder();
93 | StringBuilder sb = new StringBuilder();
94 | sbh.append("/******************\nTOP " + k + " VIOLATED CLAUSES");
95 | double tc = 0;
96 | for(int i=0; i
2 |
3 | package
4 |
5 |
6 | Misc functionalities to help develop MLN programs.
7 |
8 |