├── .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 [![Build Status](https://semaphoreci.com/api/v1/allenai/tuffylite/branches/master/badge.svg)](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 | -------------------------------------------------------------------------------- /src/main/java/tuffy/infer/ds/KeyBlock.java: -------------------------------------------------------------------------------- 1 | package tuffy.infer.ds; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedHashMap; 5 | /** 6 | * A block of ground atoms. Exactly one atom in a block can be true. 7 | */ 8 | public class KeyBlock{ 9 | 10 | public LinkedHashMap> keyConstraints = new LinkedHashMap>(); 11 | 12 | public LinkedHashMap gatom2key = new LinkedHashMap(); 13 | 14 | public void pushGAtom(Integer key, GAtom gatom){ 15 | 16 | if(!keyConstraints.containsKey(key)){ 17 | this.keyConstraints.put(key, new ArrayList()); 18 | } 19 | this.keyConstraints.get(key).add(gatom); 20 | this.gatom2key.put(gatom, key); 21 | } 22 | 23 | public boolean hasKey(GAtom gatom){ 24 | return this.gatom2key.containsKey(gatom); 25 | } 26 | 27 | public ArrayList getBlockMates(GAtom gatom){ 28 | return this.keyConstraints.get(gatom2key.get(gatom)); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/tuffy/infer/ds/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | package 4 | 5 | 6 | Data structures used to represent MRFs. 7 | 8 | -------------------------------------------------------------------------------- /src/main/java/tuffy/infer/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | package 4 | 5 | 6 | Provides MLN inference algorithms. Currently supports MAP inference and 7 | Marginal inference. 8 | 9 |

10 | By default this package deals with inference in memory. It first loads from 11 | database about information of MLN groundings. Then, it forms a MRF by taking 12 | GAtom and GClause as elements. Once this MRF is formed, this package will not 13 | interact with DBMS. 14 |

15 | 16 |

17 | Marginal and MAP inference on this in-memory structure follow classic scheme. 18 | There are indices from GClause to GAtom, vice versa. Therefore, the change 19 | of GAtom's truth assignment will influence GClause's truth value. Together with the 20 | sign of GClause's weight, whether a GClause is violated in current truth assignment 21 | setting can be tracked. The WalkSAT or MCSAT subroutines are then invoked. 22 |

23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/tuffy/infer/package_infer.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allenai/tuffylite/932ab8448c15e90bbcca87f6b3d20a2dbc7076b1/src/main/java/tuffy/infer/package_infer.jpeg -------------------------------------------------------------------------------- /src/main/java/tuffy/main/Infer.java: -------------------------------------------------------------------------------- 1 | package tuffy.main; 2 | 3 | 4 | 5 | import java.io.File; 6 | import java.util.LinkedHashMap; 7 | 8 | import tuffy.db.RDB; 9 | import tuffy.ground.Grounding; 10 | import tuffy.ground.KBMC; 11 | import tuffy.infer.DataMover; 12 | import tuffy.mln.Clause; 13 | import tuffy.mln.MarkovLogicNetwork; 14 | import tuffy.mln.Predicate; 15 | import tuffy.parse.CommandOptions; 16 | import tuffy.util.Config; 17 | import tuffy.util.ExceptionMan; 18 | import tuffy.util.FileMan; 19 | import tuffy.util.Timer; 20 | import tuffy.util.UIMan; 21 | /** 22 | * Common routines to inference procedures. 23 | */ 24 | public abstract class Infer { 25 | 26 | /** 27 | * The DB. 28 | */ 29 | protected RDB db = null; 30 | 31 | public DataMover dmover = null; 32 | 33 | /** 34 | * The MLN. 35 | */ 36 | public MarkovLogicNetwork mln = null; 37 | 38 | /** 39 | * Command line options. 40 | */ 41 | protected CommandOptions options = null; 42 | 43 | /** 44 | * Grounding worker. 45 | */ 46 | protected Grounding grounding = null; 47 | 48 | /** 49 | * Ground the MLN into an MRF. 50 | */ 51 | protected void ground(){ 52 | grounding = new Grounding(mln); 53 | grounding.dmover = dmover; 54 | grounding.constructMRF(); 55 | 56 | writeClausesToFile(); 57 | writeWCNFToFile(); 58 | } 59 | 60 | protected void writeClausesToFile() { 61 | if (Config.writeClausesFile != null) { 62 | dmover.createAtomDescTable(mln.relAtoms, Config.relAtomDesc); 63 | dmover.createClauseDescTable(mln.relClauses, Config.relClauseDesc); 64 | dmover.dumpClauseDescToFile(mln.relClauses, Config.relClauseDesc, Config.writeClausesFile); 65 | } 66 | } 67 | 68 | protected void writeWCNFToFile() { 69 | if (Config.writeWCNFFile != null) { 70 | dmover.dumpWCNFToFile(mln.relAtoms, mln.relClauses, Config.writeWCNFFile); 71 | } 72 | } 73 | 74 | /** 75 | * Set up MLN inference, including the following steps: 76 | * 77 | * 1) loadMLN {@link Infer#loadMLN}; 78 | * 2) store symbols and evidence {@link MarkovLogicNetwork#materializeTables}; 79 | * 3) run KBMC; 80 | * 4) apply scoping rules; 81 | * 5) mark query atoms in the database {@link MarkovLogicNetwork#storeAllQueries()}. 82 | * 83 | * @param opt command line options. 84 | */ 85 | protected void setUp(CommandOptions opt){ 86 | options = opt; 87 | Timer.resetClock(); 88 | 89 | Clause.mappingFromID2Const = new LinkedHashMap(); 90 | Clause.mappingFromID2Desc = new LinkedHashMap(); 91 | 92 | UIMan.println(">>> Connecting to RDBMS at " + Config.db_url); 93 | db = RDB.getRDBbyConfig(); 94 | 95 | db.resetSchema(Config.db_schema); 96 | 97 | mln = new MarkovLogicNetwork(); 98 | loadMLN(mln, db, options); 99 | 100 | mln.materializeTables(); 101 | 102 | if (Config.savePredicateNamesToDB) { 103 | savePredicateTable(mln); 104 | } 105 | 106 | KBMC kbmc = new KBMC(mln); 107 | kbmc.run(); 108 | mln.executeAllDatalogRules(); 109 | mln.applyAllScopes(); 110 | UIMan.verbose(1, ">>> Marking queries..."); 111 | mln.storeAllQueries(); 112 | 113 | for(Clause c : mln.listClauses){ 114 | if(c.isHardClause()){ 115 | c.isFixedWeight = true; 116 | }else{ 117 | c.isFixedWeight = false; 118 | } 119 | } 120 | 121 | } 122 | 123 | protected void setUp_noloading(CommandOptions opt){ 124 | options = opt; 125 | Timer.resetClock(); 126 | 127 | //Clause.mappingFromID2Const = new LinkedHashMap(); 128 | //Clause.mappingFromID2Desc = new LinkedHashMap(); 129 | 130 | UIMan.println(">>> Connecting to RDBMS at " + Config.db_url); 131 | db = RDB.getRDBbyConfig(); 132 | 133 | } 134 | 135 | protected void savePredicateTable(MarkovLogicNetwork mln) { 136 | db.dropTable(Config.relPreds); 137 | db.dropView(Config.relPreds); 138 | String sql = "CREATE TABLE " + Config.relPreds + "(\n"; 139 | sql += "predid INT,\n"; 140 | sql += "name CHARACTER VARYING);"; 141 | db.update(sql); 142 | 143 | for(Predicate p : mln.getAllPredOrderByName()){ 144 | sql = "INSERT INTO " + Config.relPreds + " VALUES ("; 145 | sql += p.getID() + ", '" + p.getRelName() + "');"; 146 | db.update(sql); 147 | } 148 | } 149 | 150 | /** 151 | * Clean up temporary data: the schema in PostgreSQL and the working directory. 152 | */ 153 | protected void cleanUp(){ 154 | Config.exiting_mode = true; 155 | UIMan.println(">>> Cleaning up temporary data"); 156 | if(!Config.keep_db_data){ 157 | UIMan.print(" Removing database schema '" + Config.db_schema + "'..."); 158 | UIMan.println(db.dropSchema(Config.db_schema)?"OK" : "FAILED"); 159 | }else{ 160 | UIMan.println(" Data remains in schema '" + Config.db_schema + "'."); 161 | } 162 | db.close(); 163 | 164 | UIMan.print(" Removing temporary dir '" + Config.getWorkingDir() + "'..."); 165 | UIMan.println(FileMan.removeDirectory(new File(Config.getWorkingDir()))?"OK" : "FAILED"); 166 | 167 | UIMan.println("*** Tuffy exited at " + Timer.getDateTime() + " after running for " + Timer.elapsed()); 168 | UIMan.closeDribbleFile(); 169 | } 170 | 171 | /** 172 | * Load the rules and data of the MLN program. 173 | * 174 | * 1) {@link MarkovLogicNetwork#loadPrograms(String[])}; 175 | * 2) {@link MarkovLogicNetwork#loadQueries(String[])}; 176 | * 3) {@link MarkovLogicNetwork#parseQueryCommaList(String)}; 177 | * 4) Mark closed-world predicate specified by {@link CommandOptions#cwaPreds}; 178 | * 5) {@link MarkovLogicNetwork#prepareDB(RDB)}; 179 | * 6) {@link MarkovLogicNetwork#loadEvidences(String[])}. 180 | * 181 | * @param mln the target MLN 182 | * @param adb database object used for this MLN 183 | * @param opt command line options 184 | */ 185 | protected void loadMLN(MarkovLogicNetwork mln, RDB adb, CommandOptions opt){ 186 | 187 | String[] progFiles = opt.fprog.split(","); 188 | mln.loadPrograms(progFiles); 189 | 190 | if(opt.fquery != null){ 191 | String[] queryFiles = opt.fquery.split(","); 192 | mln.loadQueries(queryFiles); 193 | } 194 | 195 | if(opt.queryAtoms != null){ 196 | UIMan.verbose(2, ">>> Parsing query atoms in command line"); 197 | mln.parseQueryCommaList(opt.queryAtoms); 198 | } 199 | 200 | if(opt.cwaPreds != null){ 201 | String[] preds = opt.cwaPreds.split(","); 202 | for(String ps : preds){ 203 | Predicate p = mln.getPredByName(ps); 204 | if(p == null){ 205 | mln.closeFiles(); 206 | ExceptionMan.die("COMMAND LINE: Unknown predicate name -- " + ps); 207 | }else{ 208 | p.setClosedWorld(true); 209 | } 210 | } 211 | } 212 | 213 | mln.prepareDB(adb); 214 | 215 | if(opt.fevid != null){ 216 | String[] evidFiles = opt.fevid.split(","); 217 | mln.loadEvidences(evidFiles); 218 | } 219 | 220 | dmover = new DataMover(mln); 221 | } 222 | 223 | 224 | 225 | 226 | } 227 | -------------------------------------------------------------------------------- /src/main/java/tuffy/main/Main.java: -------------------------------------------------------------------------------- 1 | package tuffy.main; 2 | 3 | import java.sql.SQLException; 4 | 5 | //import tuffy.learn.DNLearner; 6 | //import tuffy.learn.MultiCoreSGDLearner; 7 | //import tuffy.learn.SGDLearner; 8 | import tuffy.parse.CommandOptions; 9 | import tuffy.util.Config; 10 | import tuffy.util.ExceptionMan; 11 | import tuffy.util.UIMan; 12 | /** 13 | * The Main. 14 | */ 15 | public class Main { 16 | public static void main(String[] args) throws SQLException { 17 | 18 | CommandOptions options = UIMan.parseCommand(args); 19 | 20 | UIMan.println("*** Welcome to " + Config.product_name + "!"); 21 | UIMan.verbose(1, "Running with options: \n" + options); 22 | if(options == null){ 23 | return; 24 | } 25 | 26 | if(!options.isDLearningMode){ 27 | // INFERENCE 28 | if(!options.disablePartition){ 29 | UIMan.println("Partitioned inference disabled"); 30 | // new PartInfer().run(options); 31 | }else{ 32 | new NonPartInfer().run(options); 33 | // Config.reset(); 34 | // options = UIMan.parseCommand(args); 35 | // new NonPartInfer().run(options); 36 | // Config.reset(); 37 | // options = UIMan.parseCommand(args); 38 | // new NonPartInfer().run(options); 39 | } 40 | }else{ 41 | UIMan.println("Learning disabled"); 42 | // if(options.mle){ 43 | // //SGDLearner l = new SGDLearner(); 44 | // MultiCoreSGDLearner l = new MultiCoreSGDLearner(); 45 | // l.run(options); 46 | // l.cleanUp(); 47 | // 48 | // }else{ 49 | // //LEARNING 50 | // DNLearner l = new DNLearner(); 51 | // l.run(options); 52 | // } 53 | } 54 | 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/tuffy/main/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | package 4 | 5 | 6 | Entrances to Tuffy. 7 | 8 | -------------------------------------------------------------------------------- /src/main/java/tuffy/mln/Atom.java: -------------------------------------------------------------------------------- 1 | package tuffy.mln; 2 | import java.util.*; 3 | 4 | import tuffy.util.StringMan; 5 | 6 | 7 | /** 8 | * An atomic formula. It's designed as a light-weight construct, hence 9 | * all fields are transparent (public). 10 | */ 11 | public class Atom { 12 | 13 | /** 14 | * Enumerated type of Atoms. 1) NONE; 2) EVIDENCE: atom in evidence; 15 | * 3) QUERY: atom in query; 4) QUEVID: atom in query as evidence. 16 | */ 17 | public static enum AtomType {EVIDENCE, QUERY, NONE, QUEVID}; 18 | 19 | /** 20 | * The predicate of this Atom. 21 | */ 22 | 23 | public Predicate pred; 24 | /** 25 | * The argument list represented as a tuple of integers: 26 | * constant as positive number and variable as negative number. 27 | */ 28 | public Tuple args = null; 29 | 30 | public ArrayList sargs = null; 31 | 32 | /** 33 | * Truth value of this atom. 34 | */ 35 | public Boolean truth = null; 36 | 37 | /** 38 | * Probability of "soft evidence". 39 | */ 40 | public Double prior = null; 41 | 42 | /** 43 | * Type of this atom. Values are enumerated by {@link AtomType}. 44 | */ 45 | public AtomType type = AtomType.NONE; 46 | 47 | /** 48 | * Map the {@link AtomType} value of this atom into an integer, 49 | * which is used internally by the DB. 50 | */ 51 | public int club() { 52 | switch(type) { 53 | case NONE: return 0; 54 | case QUERY: return 1; 55 | case EVIDENCE: return 2; 56 | case QUEVID: return 3; // evidence in query 57 | default: return 0; 58 | } 59 | } 60 | 61 | /** 62 | * Test if this atom is soft evidence. 63 | */ 64 | public boolean isSoftEvidence(){ 65 | return prior != null; 66 | } 67 | 68 | /** 69 | * Return the number of grounded atoms when grounding this atom. 70 | * This number equals to the multiplication of the domain size 71 | * of each distinct variable appearing in this atom. That is, 72 | * we assume cross product is used. 73 | */ 74 | public long groundSize(){ 75 | long size = 1; 76 | 77 | // ASSUMPTION OF DATA STRUCTURE: $\forall$ i args.get(j) if 78 | // args.get(i), args.get(j) < 0. (i.e., naming new variables 79 | // sequentially from left to right. 80 | int lastVar = 0; 81 | for(int i=0; i as, boolean t){ 99 | pred = p; 100 | args = new Tuple(as); 101 | 102 | truth = t; 103 | type = AtomType.EVIDENCE; 104 | } 105 | 106 | public Atom(ArrayList as, double prior){ 107 | pred = null; 108 | sargs = as; 109 | truth = null; 110 | this.prior = prior; 111 | type = AtomType.NONE; 112 | } 113 | 114 | public Atom(ArrayList as, boolean t){ 115 | pred = null; 116 | sargs = as; 117 | truth = t; 118 | type = AtomType.EVIDENCE; 119 | } 120 | 121 | 122 | 123 | /** 124 | * Create an atom of type NONE. 125 | * The default truth value of unknown is null. 126 | * 127 | * @param p the predicate 128 | * @param at the arguments in the form of a tuple 129 | * 130 | * @see tuffy.ground.KBMC#run() 131 | */ 132 | public Atom(Predicate p, Tuple at){ 133 | assert(at.list.length == p.arity()); 134 | pred = p; 135 | args = at; 136 | truth = null; 137 | type = AtomType.NONE; 138 | } 139 | 140 | /** 141 | * Returns this atom's human-friendly string representation. 142 | */ 143 | public String toString() { 144 | ArrayList as = new ArrayList(); 145 | for(int v : args.list) { 146 | if(v >= 0){ 147 | as.add("C" + v); 148 | }else{ 149 | as.add("v" + (-v)); 150 | } 151 | } 152 | return pred.getName() + StringMan.commaListParen(as); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/tuffy/mln/Term.java: -------------------------------------------------------------------------------- 1 | package tuffy.mln; 2 | 3 | import tuffy.util.StringMan; 4 | 5 | /** 6 | * A term in first-order logic; either a variable or a constant. 7 | */ 8 | public class Term { 9 | 10 | /** 11 | * Whether this term is a variable. 12 | */ 13 | private boolean isVariable; 14 | 15 | 16 | /** 17 | * The name of this term. $var$ is not null iff. 18 | * this term is a variable. 19 | */ 20 | private String var = null; 21 | 22 | /** 23 | * The ID of this term. $constantID$ is not null iff. 24 | * this term is a constant. 25 | */ 26 | private Integer constantID = null; 27 | private String constantString = null; 28 | 29 | 30 | /** 31 | * Constructor of Term (variable version). 32 | * 33 | * @param var name of the variable 34 | */ 35 | public Term(String var){ 36 | isVariable = true; 37 | this.var = var; 38 | } 39 | 40 | public Term(String s, boolean isConstant) { 41 | if (isConstant) { 42 | constantString = s; 43 | isVariable = false; 44 | } else { 45 | var = s; 46 | isVariable = true; 47 | } 48 | } 49 | 50 | /** 51 | * Constructor a Term (constant version). 52 | * 53 | * @param cid the constant in the form of its integer ID 54 | */ 55 | public Term(Integer cid){ 56 | isVariable = false; 57 | constantID = cid; 58 | constantString = cid.toString(); 59 | } 60 | 61 | /** 62 | * Return whether this term is a variable. 63 | */ 64 | public boolean isVariable(){ 65 | return isVariable; 66 | } 67 | 68 | /** 69 | * 70 | * @return Whether this term is a constant. 71 | */ 72 | public boolean isConstant(){ 73 | return !isVariable; 74 | } 75 | 76 | /** 77 | * @return The name of this term, which is null when it is 78 | * a constant. 79 | */ 80 | public String var(){ 81 | return var; 82 | } 83 | 84 | /** 85 | * 86 | * @return The name of this term, which is null when it is 87 | * a variable. 88 | */ 89 | public int constant(){ 90 | return constantID; 91 | } 92 | 93 | public String constantString() { 94 | return constantString; 95 | } 96 | 97 | /** 98 | * @return This term's human-friendly representation. 99 | */ 100 | public String toString() { 101 | if(isVariable) { 102 | return var; 103 | }else { 104 | return StringMan.quoteJavaString(constantString); 105 | } 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/tuffy/mln/Tuple.java: -------------------------------------------------------------------------------- 1 | package tuffy.mln; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * A tuple of constants/variables, represented as 7 | * a transparent list of integers. 8 | * 9 | */ 10 | public class Tuple { 11 | 12 | /** 13 | * positive element = constant; 14 | * negative element = variable. 15 | * variables are encoded as -1, -2, ... 16 | */ 17 | public int[] list = null; 18 | 19 | // ASSUMPTION OF DATA STRUCTURE: the naming of variables 20 | // are assigned sequentially with increment 1 for each new variable 21 | // not seen before. 22 | 23 | /** 24 | * The degree of freedom, i.e. the number of distinct variables. 25 | * Actually, it corresponds to the smallest integer name of variables. 26 | */ 27 | public int dimension; 28 | 29 | /** 30 | * Constructor of Tuple. 31 | * Assuming args is already canonicalized 32 | * 33 | * @param args 34 | */ 35 | public Tuple(ArrayList args) { 36 | list = new int[args.size()]; 37 | dimension = 0; 38 | for(int i=0; i 0) { // a constant 77 | if(l2[i] != list[i]) return false; 78 | }else { // a variable 79 | int target = sub[-list[i]]; 80 | if(target == 0) { 81 | sub[-list[i]] = l2[i]; 82 | }else if(target != l2[i]) { 83 | return false; 84 | } 85 | } 86 | } 87 | return true; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/tuffy/mln/Type.java: -------------------------------------------------------------------------------- 1 | package tuffy.mln; 2 | import java.io.BufferedWriter; 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.OutputStreamWriter; 8 | import java.io.PipedInputStream; 9 | import java.io.PipedOutputStream; 10 | import java.io.Writer; 11 | import java.util.LinkedHashMap; 12 | import java.util.LinkedHashSet; 13 | 14 | import org.postgresql.PGConnection; 15 | 16 | import tuffy.db.RDB; 17 | import tuffy.util.Config; 18 | import tuffy.util.ExceptionMan; 19 | 20 | /** 21 | * A domain/type of constants; i.e., a subset of constants. 22 | */ 23 | public class Type { 24 | 25 | /** 26 | * Built-in types 27 | */ 28 | public static Type Generic = new Type("_GENERIC"); 29 | public static Type Float = new Type("_FLOAT"); 30 | public static Type Integer = new Type("_INTEGER"); 31 | public static Type String = new Type("_STRING"); 32 | public static Type Bool = new Type("_BOOL"); 33 | 34 | static { 35 | Float.isNonSymbolicType = true; 36 | Integer.isNonSymbolicType = true; 37 | Bool.isNonSymbolicType = true; 38 | Float.nonSymbolicType = Float; 39 | Integer.nonSymbolicType = Integer; 40 | Bool.nonSymbolicType = Bool; 41 | } 42 | 43 | private boolean isNonSymbolicType = false; 44 | 45 | private Type nonSymbolicType = null; 46 | 47 | /** 48 | * See if this type is non-symbolic. 49 | * "Non-symbolic" means that the value of this type is directly 50 | * stored in the predicate table, whereas values of a "symbolic" (default) 51 | * type are represented by unique IDs as per the symbol table. 52 | * @return 53 | */ 54 | public boolean isNonSymbolicType(){ 55 | return isNonSymbolicType; 56 | } 57 | 58 | public Type getNonSymbolicType(){ 59 | return nonSymbolicType; 60 | } 61 | 62 | public String getNonSymbolicTypeInSQL(){ 63 | if(nonSymbolicType.name.equals("_FLOAT")){ 64 | return "float"; 65 | }else if (nonSymbolicType.name.equals("_STRING")){ 66 | return "string"; 67 | }else if (nonSymbolicType.name.equals("_INTEGER")){ 68 | return "integer"; 69 | }else if (nonSymbolicType.name.equals("_BOOL")){ 70 | return "boolean"; 71 | }else{ 72 | return null; 73 | } 74 | } 75 | 76 | /** 77 | * The domain of variable values. The members of a domain are 78 | * named as integer. 79 | */ 80 | private LinkedHashSet domain = new LinkedHashSet(); 81 | 82 | /** 83 | * Name of this Type. 84 | */ 85 | public String name; 86 | 87 | /** 88 | * Name of the relational table corresponding to this type. 89 | * Here it is type_$name. 90 | */ 91 | private String relName; 92 | 93 | public boolean isProbArg = false; 94 | 95 | /** 96 | * Constructor of Type. 97 | * 98 | * @param name the name of this new type; it must be unique among all types 99 | */ 100 | public Type(String name){ 101 | this.name = name; 102 | relName = "type_" + name; 103 | 104 | if(name.endsWith("_")){ 105 | isNonSymbolicType = true; 106 | if(name.toLowerCase().startsWith("float")){ 107 | nonSymbolicType = Float; 108 | }else if(name.toLowerCase().startsWith("double")){ 109 | nonSymbolicType = Float; 110 | }else if(name.toLowerCase().startsWith("int")){ 111 | nonSymbolicType = Integer; 112 | }else{ 113 | isNonSymbolicType = false; 114 | } 115 | } 116 | 117 | if(name.endsWith("_p_")){ 118 | this.isProbArg = true; 119 | } 120 | 121 | } 122 | 123 | /** 124 | * Return the name of the DB relational table of this type. 125 | */ 126 | public String getRelName(){ 127 | return relName; 128 | } 129 | 130 | /** 131 | * Store the list of constants in a DB table. 132 | * 133 | * @param db 134 | */ 135 | public void storeConstantList(RDB db, boolean... onlyNonEmptyDomain){ 136 | 137 | if(onlyNonEmptyDomain.length>0 && onlyNonEmptyDomain[0] == true && domain.size() == 0){ 138 | return; 139 | } 140 | 141 | String sql; 142 | 143 | if(onlyNonEmptyDomain.length == 0){ 144 | db.dropTable(relName); 145 | //String sql = "CREATE TEMPORARY TABLE " + relName + "(constantID INTEGER)\n"; 146 | sql = "CREATE TABLE " + relName + "(constantID bigint, constantVALUE TEXT)"; 147 | db.update(sql); 148 | } 149 | 150 | 151 | BufferedWriter writer = null; 152 | File loadingFile = new File(Config.getLoadingDir(), "loading_type_" + name); 153 | try { 154 | writer = new BufferedWriter(new OutputStreamWriter 155 | (new FileOutputStream(loadingFile),"UTF8")); 156 | for(int v : domain) { 157 | writer.append(v + "\n"); 158 | } 159 | writer.close(); 160 | 161 | FileInputStream in = new FileInputStream(loadingFile); 162 | PGConnection con = (PGConnection)db.getConnection(); 163 | sql = "COPY " + relName + " (constantID) FROM STDIN "; 164 | con.getCopyAPI().copyIn(sql, in); 165 | in.close(); 166 | 167 | sql = "UPDATE " + relName + " SET constantVALUE = t1.string FROM " + Config.relConstants + " t1 WHERE t1.id = constantID AND constantVALUE IS NULL"; 168 | db.execute(sql); 169 | 170 | //domain.clear(); 171 | }catch(Exception e) { 172 | ExceptionMan.handle(e); 173 | } 174 | 175 | db.analyze(relName); 176 | } 177 | 178 | /** 179 | * Add a constant to this type. 180 | * 181 | * @param con the constant to be added 182 | */ 183 | public void addConstant(int con) { 184 | domain.add(con); 185 | } 186 | 187 | public LinkedHashSet getDomain(){ 188 | return domain; 189 | } 190 | 191 | /** 192 | * Return true if this type contains the constant x 193 | */ 194 | public boolean contains(int x){ 195 | return domain.contains(x); 196 | } 197 | 198 | /** 199 | * Return the number of constants in this type domain. 200 | */ 201 | public int size(){ 202 | RDB db = RDB.getRDBbyConfig(Config.db_schema); 203 | int a = (int) db.countTuples(this.relName); 204 | db.close(); 205 | return a; 206 | // return domain.size(); 207 | } 208 | 209 | /** 210 | * Return the name of this type. 211 | */ 212 | public String name(){ 213 | return name; 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/main/java/tuffy/mln/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | package 4 | 5 | 6 | 7 | This package builds the data structure of MLN. 8 | 9 |

10 | This package defines the data structure representing logics, e.g., 11 | Atom, Predicate, Term, etc. Also, it bridges these objects to 12 | relational tables in DBMS. 13 |

14 | 15 |

16 | Following figure illustrates the relationship between classes in this 17 | package, and the relationship between class and database table. For example, 18 | from this figure, we can see that, an Atom object is formed by a Tuple object 19 | and a Predicate object. And a Predicate object is associated with two 20 | database tables. 21 |

22 | 23 |

24 | There are four kinds of database tables. type_TypeName table saves the constant 25 | ID of type TypeName. pred_PredicateName table saves grounded instances of predicate 26 | PredicateName. 27 | act_pred_PredicateName table saves the active atoms of predicate PredicateName. 28 | ClauseName_instances table saves instances of clause ClauseName. Here by instance, 29 | it means the possible binding from meta-variable to constant. By such bindings, you 30 | can get clauses as the same as your input program. 31 |

32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/tuffy/mln/package_mln.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allenai/tuffylite/932ab8448c15e90bbcca87f6b3d20a2dbc7076b1/src/main/java/tuffy/mln/package_mln.jpeg -------------------------------------------------------------------------------- /src/main/java/tuffy/parse/Config.g: -------------------------------------------------------------------------------- 1 | grammar Config; 2 | options {language=Java; output=AST; backtrack=false; memoize=false;} 3 | 4 | @lexer::header { 5 | package tuffy.parse; 6 | } 7 | 8 | @parser::header{ 9 | package tuffy.parse; 10 | import java.util.Hashtable; 11 | import tuffy.mln.*; 12 | import tuffy.util.*; 13 | } 14 | 15 | @parser::members { 16 | public Hashtable map = new Hashtable(); 17 | } 18 | 19 | WS : (' ' 20 | | '\r' 21 | | '\n' 22 | | '\t' 23 | ) {$channel=HIDDEN;} 24 | ; 25 | 26 | COMMENT 27 | : (('#' ~('\n'|'\r')* '\r'? '\n')) {$channel=HIDDEN;} 28 | ; 29 | 30 | SPAN: ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-'|':'|'/'|'\\'|'\.')+; 31 | 32 | config : (state)+ EOF; 33 | 34 | state : id=SPAN '=' value=SPAN 35 | { 36 | map.put($id.text, $value.text); 37 | } 38 | ; 39 | -------------------------------------------------------------------------------- /src/main/java/tuffy/parse/Config.tokens: -------------------------------------------------------------------------------- 1 | WS=4 2 | SPAN=6 3 | COMMENT=5 4 | T__7=7 5 | '='=7 6 | -------------------------------------------------------------------------------- /src/main/java/tuffy/parse/ConfigParser.java: -------------------------------------------------------------------------------- 1 | // $ANTLR 3.2 Sep 23, 2009 12:02:23 /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g 2012-02-17 15:34:25 2 | 3 | package tuffy.parse; 4 | import java.util.Hashtable; 5 | import tuffy.mln.*; 6 | import tuffy.util.*; 7 | 8 | 9 | import org.antlr.runtime.*; 10 | import java.util.Stack; 11 | import java.util.List; 12 | import java.util.ArrayList; 13 | 14 | 15 | import org.antlr.runtime.tree.*; 16 | 17 | public class ConfigParser extends Parser { 18 | public static final String[] tokenNames = new String[] { 19 | "", "", "", "", "WS", "COMMENT", "SPAN", "'='" 20 | }; 21 | public static final int WS=4; 22 | public static final int SPAN=6; 23 | public static final int COMMENT=5; 24 | public static final int EOF=-1; 25 | public static final int T__7=7; 26 | 27 | // delegates 28 | // delegators 29 | 30 | 31 | public ConfigParser(TokenStream input) { 32 | this(input, new RecognizerSharedState()); 33 | } 34 | public ConfigParser(TokenStream input, RecognizerSharedState state) { 35 | super(input, state); 36 | 37 | } 38 | 39 | protected TreeAdaptor adaptor = new CommonTreeAdaptor(); 40 | 41 | public void setTreeAdaptor(TreeAdaptor adaptor) { 42 | this.adaptor = adaptor; 43 | } 44 | public TreeAdaptor getTreeAdaptor() { 45 | return adaptor; 46 | } 47 | 48 | public String[] getTokenNames() { return ConfigParser.tokenNames; } 49 | public String getGrammarFileName() { return "/scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g"; } 50 | 51 | 52 | public Hashtable map = new Hashtable(); 53 | 54 | 55 | public static class config_return extends ParserRuleReturnScope { 56 | Object tree; 57 | public Object getTree() { return tree; } 58 | }; 59 | 60 | // $ANTLR start "config" 61 | // /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g:32:1: config : ( state )+ EOF ; 62 | public final ConfigParser.config_return config() throws RecognitionException { 63 | ConfigParser.config_return retval = new ConfigParser.config_return(); 64 | retval.start = input.LT(1); 65 | 66 | Object root_0 = null; 67 | 68 | Token EOF2=null; 69 | ConfigParser.state_return state1 = null; 70 | 71 | 72 | Object EOF2_tree=null; 73 | 74 | try { 75 | // /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g:32:8: ( ( state )+ EOF ) 76 | // /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g:32:11: ( state )+ EOF 77 | { 78 | root_0 = (Object)adaptor.nil(); 79 | 80 | // /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g:32:11: ( state )+ 81 | int cnt1=0; 82 | loop1: 83 | do { 84 | int alt1=2; 85 | int LA1_0 = input.LA(1); 86 | 87 | if ( (LA1_0==SPAN) ) { 88 | alt1=1; 89 | } 90 | 91 | 92 | switch (alt1) { 93 | case 1 : 94 | // /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g:32:12: state 95 | { 96 | pushFollow(FOLLOW_state_in_config196); 97 | state1=state(); 98 | 99 | state._fsp--; 100 | 101 | adaptor.addChild(root_0, state1.getTree()); 102 | 103 | } 104 | break; 105 | 106 | default : 107 | if ( cnt1 >= 1 ) break loop1; 108 | EarlyExitException eee = 109 | new EarlyExitException(1, input); 110 | throw eee; 111 | } 112 | cnt1++; 113 | } while (true); 114 | 115 | EOF2=(Token)match(input,EOF,FOLLOW_EOF_in_config200); 116 | EOF2_tree = (Object)adaptor.create(EOF2); 117 | adaptor.addChild(root_0, EOF2_tree); 118 | 119 | 120 | } 121 | 122 | retval.stop = input.LT(-1); 123 | 124 | retval.tree = (Object)adaptor.rulePostProcessing(root_0); 125 | adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); 126 | 127 | } 128 | catch (RecognitionException re) { 129 | reportError(re); 130 | recover(input,re); 131 | retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re); 132 | 133 | } 134 | finally { 135 | } 136 | return retval; 137 | } 138 | // $ANTLR end "config" 139 | 140 | public static class state_return extends ParserRuleReturnScope { 141 | Object tree; 142 | public Object getTree() { return tree; } 143 | }; 144 | 145 | // $ANTLR start "state" 146 | // /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g:34:1: state : id= SPAN '=' value= SPAN ; 147 | public final ConfigParser.state_return state() throws RecognitionException { 148 | ConfigParser.state_return retval = new ConfigParser.state_return(); 149 | retval.start = input.LT(1); 150 | 151 | Object root_0 = null; 152 | 153 | Token id=null; 154 | Token value=null; 155 | Token char_literal3=null; 156 | 157 | Object id_tree=null; 158 | Object value_tree=null; 159 | Object char_literal3_tree=null; 160 | 161 | try { 162 | // /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g:34:7: (id= SPAN '=' value= SPAN ) 163 | // /scratch/leonn/workspace/tuffy/src/tuffy/parse/Config.g:34:9: id= SPAN '=' value= SPAN 164 | { 165 | root_0 = (Object)adaptor.nil(); 166 | 167 | id=(Token)match(input,SPAN,FOLLOW_SPAN_in_state210); 168 | id_tree = (Object)adaptor.create(id); 169 | adaptor.addChild(root_0, id_tree); 170 | 171 | char_literal3=(Token)match(input,7,FOLLOW_7_in_state212); 172 | char_literal3_tree = (Object)adaptor.create(char_literal3); 173 | adaptor.addChild(root_0, char_literal3_tree); 174 | 175 | value=(Token)match(input,SPAN,FOLLOW_SPAN_in_state216); 176 | value_tree = (Object)adaptor.create(value); 177 | adaptor.addChild(root_0, value_tree); 178 | 179 | 180 | map.put((id!=null?id.getText():null), (value!=null?value.getText():null)); 181 | 182 | 183 | } 184 | 185 | retval.stop = input.LT(-1); 186 | 187 | retval.tree = (Object)adaptor.rulePostProcessing(root_0); 188 | adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop); 189 | 190 | } 191 | catch (RecognitionException re) { 192 | reportError(re); 193 | recover(input,re); 194 | retval.tree = (Object)adaptor.errorNode(input, retval.start, input.LT(-1), re); 195 | 196 | } 197 | finally { 198 | } 199 | return retval; 200 | } 201 | // $ANTLR end "state" 202 | 203 | // Delegated rules 204 | 205 | 206 | 207 | 208 | public static final BitSet FOLLOW_state_in_config196 = new BitSet(new long[]{0x0000000000000040L}); 209 | public static final BitSet FOLLOW_EOF_in_config200 = new BitSet(new long[]{0x0000000000000002L}); 210 | public static final BitSet FOLLOW_SPAN_in_state210 = new BitSet(new long[]{0x0000000000000080L}); 211 | public static final BitSet FOLLOW_7_in_state212 = new BitSet(new long[]{0x0000000000000040L}); 212 | public static final BitSet FOLLOW_SPAN_in_state216 = new BitSet(new long[]{0x0000000000000002L}); 213 | 214 | } -------------------------------------------------------------------------------- /src/main/java/tuffy/parse/InputParser.java: -------------------------------------------------------------------------------- 1 | package tuffy.parse; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.InputStream; 5 | import java.util.zip.GZIPInputStream; 6 | 7 | 8 | 9 | 10 | import org.antlr.runtime.ANTLRInputStream; 11 | import org.antlr.runtime.ANTLRStringStream; 12 | import org.antlr.runtime.CharStream; 13 | import org.antlr.runtime.CommonTokenStream; 14 | 15 | import tuffy.mln.MarkovLogicNetwork; 16 | import tuffy.util.Config; 17 | import tuffy.util.ExceptionMan; 18 | import tuffy.util.UIMan; 19 | 20 | public class InputParser { 21 | MarkovLogicNetwork mln; 22 | 23 | public InputParser(MarkovLogicNetwork amln){ 24 | mln = amln; 25 | } 26 | 27 | public void parseProgramFile(String fprog){ 28 | MLNParser parser = new MLNParser(getTokens(fprog)); 29 | parser.ml = this.mln; 30 | try { 31 | parser.definitions(); 32 | } catch (Exception e) { 33 | mln.closeFiles(); 34 | ExceptionMan.handle(e); 35 | } 36 | } 37 | 38 | public void parseEvidenceFile(String fevid){ 39 | MLNParser parser = new MLNParser(getTokens(fevid)); 40 | parser.ml = this.mln; 41 | try { 42 | parser.evidenceList(); 43 | } catch (Exception e) { 44 | mln.closeFiles(); 45 | ExceptionMan.handle(e); 46 | } 47 | } 48 | 49 | 50 | public void parseEvidenceString(String chunk, long lineOffset){ 51 | ANTLRStringStream input = new ANTLRStringStream(chunk); 52 | MLNLexer lexer = new MLNLexer(input); 53 | CommonTokenStream tokens = new CommonTokenStream(lexer); 54 | MLNParser parser = new MLNParser(tokens); 55 | parser.lineOffset = lineOffset; 56 | parser.ml = this.mln; 57 | try { 58 | parser.evidenceList(); 59 | parser.reset(); 60 | tokens.reset(); 61 | lexer.reset(); 62 | input.reset(); 63 | parser.ml = null; 64 | parser = null; 65 | } catch (Exception e) { 66 | mln.closeFiles(); 67 | ExceptionMan.handle(e); 68 | } 69 | } 70 | 71 | 72 | public void parseQueryFile(String fquery){ 73 | MLNParser parser = new MLNParser(getTokens(fquery)); 74 | parser.ml = this.mln; 75 | try { 76 | parser.queryList(); 77 | } catch (Exception e) { 78 | mln.closeFiles(); 79 | ExceptionMan.handle(e); 80 | } 81 | } 82 | 83 | public void parseQueryCommaList(String queryAtoms){ 84 | CharStream input = new ANTLRStringStream(queryAtoms); 85 | MLNLexer lexer = new MLNLexer(input); 86 | CommonTokenStream tokens = new CommonTokenStream(lexer); 87 | MLNParser parser = new MLNParser(tokens); 88 | parser.ml = this.mln; 89 | try { 90 | parser.queryCommaList(); 91 | } catch (Exception e) { 92 | mln.closeFiles(); 93 | ExceptionMan.handle(e); 94 | } 95 | } 96 | 97 | private CommonTokenStream getTokens(String fname){ 98 | try { 99 | InputStream is; 100 | FileInputStream fis = new FileInputStream(fname); 101 | if(fname.toLowerCase().endsWith(".gz")){ 102 | is = new GZIPInputStream(fis); 103 | }else{ 104 | is = fis; 105 | } 106 | ANTLRInputStream input = new ANTLRInputStream(is); 107 | MLNLexer lexer = new MLNLexer(input); 108 | CommonTokenStream tokens = new CommonTokenStream(lexer); 109 | is.close(); 110 | return tokens; 111 | } catch (Exception e) { 112 | ExceptionMan.handle(e); 113 | } 114 | return null; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/tuffy/parse/MLN.tokens: -------------------------------------------------------------------------------- 1 | EXPONENT=19 2 | T__29=29 3 | T__28=28 4 | T__27=27 5 | T__26=26 6 | T__25=25 7 | T__24=24 8 | T__23=23 9 | ESC=13 10 | T__22=22 11 | T__21=21 12 | FLOAT=17 13 | NOT=6 14 | ID=20 15 | T__61=61 16 | T__60=60 17 | ASTERISK=9 18 | T__55=55 19 | T__56=56 20 | T__57=57 21 | T__58=58 22 | T__51=51 23 | T__52=52 24 | T__53=53 25 | T__54=54 26 | T__59=59 27 | PLUS=7 28 | COMMENT=5 29 | T__50=50 30 | INTEGER=16 31 | T__42=42 32 | T__43=43 33 | T__40=40 34 | T__41=41 35 | T__46=46 36 | IMPLIES=12 37 | T__47=47 38 | T__44=44 39 | T__45=45 40 | PERIOD=10 41 | T__48=48 42 | T__49=49 43 | NUMBER=18 44 | MINUS=8 45 | T__30=30 46 | T__31=31 47 | T__32=32 48 | WS=4 49 | T__33=33 50 | T__34=34 51 | T__35=35 52 | T__36=36 53 | T__37=37 54 | T__38=38 55 | T__39=39 56 | STRING=14 57 | HEXDIGIT=15 58 | EXIST=11 59 | 'priorProb'=39 60 | '!'=6 61 | '|'=57 62 | 'NOT'=47 63 | '>='=52 64 | '#'=34 65 | '~'=61 66 | '/'=55 67 | '[+Label]'=32 68 | ':='=41 69 | '>'=51 70 | '||'=43 71 | '&&'=45 72 | ';'=29 73 | '='=40 74 | '<>'=48 75 | 'FD'=27 76 | '@'=22 77 | '+'=7 78 | ':-'=36 79 | ')'=25 80 | '^'=58 81 | 'AND'=46 82 | '%'=54 83 | '->'=30 84 | 'v'=42 85 | '>>'=60 86 | '$'=35 87 | 'OR'=44 88 | 'FUNCTIONAL DEPENDENCY'=26 89 | '[Label+]'=33 90 | '<<'=59 91 | '<='=50 92 | '!='=53 93 | '[Label]'=31 94 | '<'=49 95 | ':'=28 96 | '('=23 97 | '*'=9 98 | '-'=8 99 | '**'=21 100 | '['=37 101 | ','=24 102 | '&'=56 103 | ']'=38 104 | -------------------------------------------------------------------------------- /src/main/java/tuffy/parse/antlr-home/lib/antlr-3.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allenai/tuffylite/932ab8448c15e90bbcca87f6b3d20a2dbc7076b1/src/main/java/tuffy/parse/antlr-home/lib/antlr-3.2.jar -------------------------------------------------------------------------------- /src/main/java/tuffy/parse/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | package 4 | 5 | 6 | Provides parsers for MLN input, config files, and command line options. 7 | 8 |
    9 |
  • InputParser: parsing MLN programs, evidence files, and query atoms 10 |
  • ConfigParser: parsing the configuration file 11 |
  • CommandOptions: parsing command line options 12 |
13 | 14 | The first two use ANTLR, while CommandOptions is based on args4j. 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/tuffy/ra/AtomEx.java: -------------------------------------------------------------------------------- 1 | package tuffy.ra; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedHashSet; 5 | 6 | import tuffy.mln.Predicate; 7 | 8 | /** 9 | * STILL IN DEVELOPMENT. 10 | * An atomic formula with possibly functional arguments. 11 | * 12 | */ 13 | public class AtomEx{ 14 | private Predicate pred; 15 | private ArrayList args = new ArrayList(); 16 | private LinkedHashSet vars = new LinkedHashSet(); 17 | 18 | public ArrayList getArguments(){ 19 | return args; 20 | } 21 | 22 | public boolean isBuiltIn(){ 23 | return pred.isBuiltIn(); 24 | } 25 | 26 | public AtomEx(Predicate predicate){ 27 | this.pred = predicate; 28 | } 29 | 30 | /** 31 | * Returns the set of variable names in this literal. 32 | */ 33 | public LinkedHashSet getVars(){ 34 | return vars; 35 | } 36 | 37 | /** 38 | * Returns the predicate of this literal. 39 | */ 40 | public Predicate getPred() { 41 | return pred; 42 | } 43 | 44 | public String toSQL(){ 45 | // cast argument into correct types 46 | return null; 47 | } 48 | 49 | 50 | /** 51 | * Appends a new term. 52 | * 53 | * @param t the term to be appended 54 | */ 55 | public void appendTerm(Expression t){ 56 | args.add(t); 57 | vars.addAll(t.getVars()); 58 | } 59 | 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/tuffy/ra/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | package 4 | 5 | 6 | Rich logic/relational constructs such as expressions and Datalog. 7 | 8 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/AtomTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.util.ArrayList; 6 | 7 | 8 | import org.junit.Test; 9 | 10 | import tuffy.mln.Atom; 11 | import tuffy.mln.Predicate; 12 | import tuffy.mln.Tuple; 13 | import tuffy.mln.Type; 14 | 15 | /** 16 | * Testing class for {@link Atom} object. 17 | * 18 | */ 19 | public class AtomTest { 20 | 21 | /** 22 | * Test function grounding atoms according to Predicate 23 | * and Constant Table. 24 | */ 25 | @Test 26 | public final void testGroundSize() { 27 | Predicate p = new Predicate(null, "dummyp", true); 28 | Type t = new Type("imatype"); 29 | t.addConstant(1); 30 | t.addConstant(2); 31 | t.addConstant(3); 32 | p.appendArgument(t); 33 | p.appendArgument(t); 34 | 35 | 36 | ArrayList list = new ArrayList(); 37 | list.add(2); 38 | list.add(3); 39 | Atom atom = new Atom(p, list, true); 40 | 41 | assertEquals(1, atom.groundSize()); 42 | 43 | list = new ArrayList(); 44 | list.add(-1); 45 | list.add(3); 46 | Tuple tmpTuple = new Tuple(list); 47 | atom = new Atom(p, tmpTuple); 48 | assertEquals(p.arity(), tmpTuple.list.length); 49 | assertEquals(3, atom.groundSize()); 50 | 51 | list = new ArrayList(); 52 | list.add(-1); 53 | list.add(-1); 54 | atom = new Atom(p, list, true); 55 | assertEquals(3, atom.groundSize()); 56 | 57 | list = new ArrayList(); 58 | list.add(-1); 59 | list.add(-2); 60 | atom = new Atom(p, list, true); 61 | assertEquals(9, atom.groundSize()); 62 | 63 | atom.type = Atom.AtomType.QUERY; 64 | assertEquals(1, atom.club()); 65 | 66 | atom.type = Atom.AtomType.QUEVID; 67 | assertEquals(3, atom.club()); 68 | 69 | } 70 | 71 | /** 72 | * Test function transforming Atom object to String 73 | * representation. 74 | */ 75 | @Test 76 | public final void testToString() { 77 | Predicate p = new Predicate(null, "pred", true); 78 | Type t = new Type("imatype"); 79 | t.addConstant(1); 80 | t.addConstant(2); 81 | t.addConstant(3); 82 | p.appendArgument(t); 83 | p.appendArgument(t); 84 | 85 | ArrayList list = new ArrayList(); 86 | list.add(2); 87 | list.add(3); 88 | Atom atom = new Atom(p, list, true); 89 | assertEquals("pred(C2, C3)", atom.toString()); 90 | 91 | list = new ArrayList(); 92 | list.add(-1); 93 | list.add(3); 94 | atom = new Atom(p, list, true); 95 | assertEquals("pred(v1, C3)", atom.toString()); 96 | 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/ClauseTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.util.LinkedHashMap; 6 | 7 | 8 | import org.junit.BeforeClass; 9 | import org.junit.Test; 10 | 11 | 12 | import tuffy.db.RDB; 13 | import tuffy.mln.Clause; 14 | import tuffy.mln.Literal; 15 | import tuffy.mln.MarkovLogicNetwork; 16 | import tuffy.mln.Predicate; 17 | import tuffy.mln.Term; 18 | import tuffy.mln.Type; 19 | import tuffy.ra.ConjunctiveQuery; 20 | import tuffy.util.Config; 21 | 22 | /** 23 | * Testing Class for {@link Clause} object. 24 | * 25 | */ 26 | public class ClauseTest { 27 | 28 | private static Predicate p1, p2; 29 | private static Type type; 30 | 31 | @BeforeClass 32 | public static final void setUp(){ 33 | p1 = new Predicate(null, "pred1", true); 34 | p2 = new Predicate(null, "pred2", true); 35 | p2.setClosedWorld(false); 36 | type = new Type("imatype"); 37 | type.addConstant(1); 38 | type.addConstant(2); 39 | type.addConstant(3); 40 | p1.appendArgument(type); 41 | p2.appendArgument(type); 42 | p2.appendArgument(type); 43 | } 44 | 45 | 46 | /** 47 | * Test the DB-related functions of clauses, e.g., 48 | * clause instance table for each Clause. 49 | */ 50 | @Test 51 | public final void testClauseDB() { 52 | 53 | ConjunctiveQuery.clearIndexHistory(); 54 | 55 | Clause.mappingFromID2Const = new LinkedHashMap(); 56 | Clause.mappingFromID2Desc = new LinkedHashMap(); 57 | 58 | Clause c1 = new Clause(); 59 | Literal lit1 = new Literal(p1, true); 60 | lit1.appendTerm(new Term(2)); 61 | c1.addLiteral(lit1); 62 | 63 | Literal lit2 = new Literal(p2, false); 64 | lit2.appendTerm(new Term("x")); 65 | lit2.appendTerm(new Term(2)); 66 | c1.addLiteral(lit2); 67 | 68 | /* 69 | Literal lit3 = new Literal(Predicate.Same, false); 70 | lit3.appendTerm(new Term("x")); 71 | lit3.appendTerm(new Term("x")); 72 | c1.addLiteral(lit3); 73 | */ 74 | 75 | c1.setWeight(3); 76 | c1 = c1.normalize(); 77 | c1.setName("dummyclause"); 78 | RDB db = RDB.getRDBbyConfig(); 79 | System.out.println(Config.db_schema); 80 | db.resetSchema(Config.db_schema); 81 | c1.prepareForDB(db); 82 | String table = c1.getName() + "_instances"; 83 | long n = db.countTuples(table); 84 | assertEquals(1, n); 85 | db.dropSchema(Config.db_schema); 86 | } 87 | 88 | /** 89 | * Test the normalize function of Clause. 90 | */ 91 | @Test 92 | public final void testNormalize() { 93 | Clause c1 = new Clause(); 94 | Clause c2 = new Clause(); 95 | Literal lit1 = new Literal(p1, true); 96 | lit1.appendTerm(new Term(2)); 97 | c1.addLiteral(lit1); 98 | c2.addLiteral(lit1); 99 | 100 | Literal lit2 = new Literal(p2, false); 101 | lit2.appendTerm(new Term("x")); 102 | lit2.appendTerm(new Term(3)); 103 | c1.addLiteral(lit2); 104 | 105 | Literal lit3 = new Literal(p2, false); 106 | lit3.appendTerm(new Term("g")); 107 | lit3.appendTerm(new Term(1)); 108 | c2.addLiteral(lit3); 109 | 110 | c1.setWeight(3); 111 | c2.setHardWeight(); 112 | assertEquals(c1.normalize().getSignature(), c2.normalize().getSignature()); 113 | } 114 | 115 | /** 116 | * Test the absorb function of clauses. 117 | */ 118 | @Test 119 | public final void testAbsorb() { 120 | Clause c1 = new Clause(); 121 | Clause c2 = new Clause(); 122 | Literal lit1 = new Literal(p1, true); 123 | lit1.appendTerm(new Term(2)); 124 | c1.addLiteral(lit1); 125 | c2.addLiteral(lit1); 126 | 127 | Literal lit2 = new Literal(p2, false); 128 | lit2.appendTerm(new Term("x")); 129 | lit2.appendTerm(new Term(3)); 130 | c1.addLiteral(lit2); 131 | 132 | Literal lit3 = new Literal(p2, false); 133 | lit3.appendTerm(new Term("g")); 134 | lit3.appendTerm(new Term(1)); 135 | c2.addLiteral(lit3); 136 | 137 | c1.setWeight(3); 138 | c2.setHardWeight(); 139 | c1 = c1.normalize(); 140 | c2 = c2.normalize(); 141 | c1.absorb(c2); 142 | assertTrue(c1.getWeightExp() != Double.toString(3)); 143 | 144 | Config.reorder_literals = true; 145 | 146 | c1 = c1.normalize(); 147 | String tmp = c1.toString(); 148 | tmp = tmp.replaceAll("\n", ""); 149 | tmp = tmp.replaceAll("\r", ""); 150 | assertTrue(tmp.matches("^.*pred1.*pred2.*$")); 151 | 152 | c1.getRegLiterals().get(1).getPred().setClosedWorld(true); 153 | c1 = c1.normalize(); 154 | tmp = c1.toString(); 155 | tmp = tmp.replaceAll("\n", ""); 156 | tmp = tmp.replaceAll("\r", ""); 157 | assertTrue(tmp.matches("^.*!pred2.*pred1.*$")); 158 | 159 | c1.getRegLiterals().get(0).getPred().setClosedWorld(false); 160 | c1.getRegLiterals().get(0).setSense(true); 161 | c1 = c1.normalize(); 162 | tmp = c1.toString(); 163 | tmp = tmp.replaceAll("\n", ""); 164 | tmp = tmp.replaceAll("\r", ""); 165 | assertTrue(tmp.matches("^.*pred1.*[^!]pred2.*$")); 166 | 167 | Config.reorder_literals = false; 168 | } 169 | 170 | /** 171 | * Test other functions related to clause. 172 | */ 173 | @Test 174 | public final void testMisc() { 175 | 176 | Clause c1 = new Clause(); 177 | Literal lit1 = new Literal(p1, true); 178 | lit1.appendTerm(new Term(2)); 179 | c1.addLiteral(lit1); 180 | 181 | Literal lit2 = new Literal(p2, false); 182 | lit2.appendTerm(new Term("x")); 183 | lit2.appendTerm(new Term(2)); 184 | c1.addLiteral(lit2); 185 | 186 | c1.setWeight(3); 187 | c1.generateSQL(); 188 | assertEquals("CAST(3.0 AS FLOAT8)", c1.getWeightExp()); 189 | assertEquals(true, Math.abs(c1.getWeight()-3.0)<0.01); 190 | 191 | c1.setHardWeight(); 192 | c1.generateSQL(); 193 | assertEquals("CAST(" + Double.toString(Config.hard_weight) + " AS FLOAT8)", 194 | c1.getWeightExp()); 195 | assertTrue(c1.isPositiveClause()); 196 | 197 | assertEquals(2, c1.getRegLiterals().size()); 198 | assertEquals(2, c1.getReferencedPredicates().size()); 199 | assertEquals(1, c1.getLiteralsOfPredicate(p1).size()); 200 | 201 | assertFalse(c1.hasExistentialQuantifiers()); 202 | c1.addExistentialVariable("x"); 203 | assertTrue(c1.hasExistentialQuantifiers()); 204 | 205 | //////////////////////////////////////////////////////////////////// 206 | c1 = c1.normalize(); 207 | assertEquals(true, c1.isTemplate()); 208 | 209 | //////////////////////////////////////////////////////////////////// 210 | 211 | MarkovLogicNetwork mln = new MarkovLogicNetwork(); 212 | mln.registerPred(p1); 213 | mln.registerPred(p2); 214 | mln.registerClause(c1); 215 | mln.normalizeClauses(); 216 | Clause tmpc = mln.getClauseById(1); 217 | assertEquals(0, tmpc.getId()-1-c1.getId()); 218 | 219 | tmpc = mln.getClauseById(-1); 220 | assertEquals(0, tmpc.getId()-1-c1.getId()); 221 | 222 | tmpc = mln.getClauseById(0); 223 | assertEquals(null, tmpc); 224 | 225 | } 226 | 227 | } 228 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/ConfigTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | import tuffy.util.Config; 8 | import tuffy.util.FileMan; 9 | import tuffy.util.UIMan; 10 | 11 | /** 12 | * Testing class for loading configuration file. 13 | * 14 | */ 15 | public class ConfigTest { 16 | 17 | /** 18 | * Test the function of parsing configuration file. 19 | */ 20 | @Test 21 | public final void testParseConfigFile() { 22 | String conf = "# JDBC connection string; must be PostgreSQL\r\n" + 23 | "db_url = jdbc:postgresql://localhost:5432/lmn\r\n" + 24 | "\r\n" + 25 | "# Database username; must be a superuser\r\n" + 26 | "db_username = tuffer\r\n" + 27 | "\r\n" + 28 | "# The password for db_username\r\n" + 29 | "db_password = strongPasswoRd\r\n" + 30 | "\r\n" + 31 | "# The working directory; Tuffy may write sizable temporary data here\r\n" + 32 | "dir_working = /tmp/tuffy-workspace"; 33 | 34 | FileMan.ensureExistence(Config.dir_tests); 35 | String fprog = Config.dir_tests + "/conf"; 36 | FileMan.writeToFile(fprog, conf); 37 | UIMan.parseConfigFile(fprog); 38 | FileMan.removeFile(fprog); 39 | assertEquals("tuffer", Config.db_username); 40 | assertEquals("pass", Config.db_password); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/GAtomTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | import tuffy.infer.ds.GAtom; 8 | import tuffy.infer.ds.GClause; 9 | 10 | /** 11 | * Testing class for {@link GAtom} object. 12 | * 13 | */ 14 | public class GAtomTest { 15 | 16 | GAtom atom = new GAtom(100); 17 | 18 | /** 19 | * Test the function of flipping a GAtom. 20 | */ 21 | @Test 22 | public final void test_GAtom_flip() { 23 | //flip 24 | atom.fixed = false; 25 | atom.truth = true; 26 | atom.flip(); 27 | assertEquals(false, atom.truth); 28 | atom.flip(); 29 | assertEquals(true, atom.truth); 30 | //flip (fixed) 31 | atom.fixed = true; 32 | atom.flip(); 33 | assertEquals(true, atom.truth); 34 | atom.flip(); 35 | assertEquals(true, atom.truth); 36 | } 37 | 38 | /** 39 | * Test the function of invoke and revoke a GAtom, and 40 | * its influence on calculating the cost of flipping 41 | * a GAtom. 42 | */ 43 | @Test 44 | public final void test_GAtom_invoke_revoke() { 45 | //revoke/assign GClause. 46 | GClause f = new GClause(); 47 | f.weight = 100; 48 | atom.assignSatPotential(f); 49 | assertTrue(Math.abs(atom.delta()-(-100))<0.1); 50 | atom.revokeSatPotential(f); 51 | assertTrue(Math.abs(atom.delta()-(0))<0.1); 52 | atom.assignUnsatPotential(f); 53 | assertTrue(Math.abs(atom.delta()-(100))<0.1); 54 | atom.revokeUnsatPotential(f); 55 | assertTrue(Math.abs(atom.delta()-(0))<0.1); 56 | f.weight = -100; 57 | atom.assignSatPotential(f); 58 | assertTrue(Math.abs(atom.delta()-(100))<0.1); 59 | atom.revokeSatPotential(f); 60 | assertTrue(Math.abs(atom.delta()-(0))<0.1); 61 | atom.assignUnsatPotential(f); 62 | assertTrue(Math.abs(atom.delta()-(-100))<0.1); 63 | atom.revokeUnsatPotential(f); 64 | assertTrue(Math.abs(atom.delta()-(0))<0.1); 65 | } 66 | 67 | /** 68 | * Test the function of returning the ideal value of 69 | * a GAtom. 70 | */ 71 | @Test 72 | public final void test_GAtom_wannabe() { 73 | //wannabe 74 | atom.wannabe = 3; 75 | assertTrue(atom.critical()); 76 | atom.wannabe = 1; 77 | assertTrue(atom.wannaBeFalse()); 78 | atom.wannabe = 2; 79 | assertTrue(atom.wannaBeTrue()); 80 | atom.markCritical(); 81 | assertTrue(atom.critical()); 82 | atom.markWannaBeFalse(); 83 | assertTrue(atom.wannaBeFalse()); 84 | atom.markWannaBeTrue(); 85 | assertTrue(atom.wannaBeTrue()); 86 | } 87 | 88 | 89 | 90 | } -------------------------------------------------------------------------------- /src/main/java/tuffy/test/GClauseTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | 6 | import java.util.LinkedHashMap; 7 | 8 | import org.junit.Test; 9 | 10 | import tuffy.infer.ds.GAtom; 11 | import tuffy.infer.ds.GClause; 12 | 13 | /** 14 | * Testing class for {@link GClause} object. 15 | * 16 | */ 17 | public class GClauseTest { 18 | 19 | static GClause gc = new GClause(); 20 | 21 | /** 22 | * Test weight-related function of GClause, i.e., 23 | * the relationships between 1) weight; 2) cost and 24 | * 3) # satisfied GAtom in GClause. 25 | */ 26 | @Test 27 | public final void test_GClause_weight(){ 28 | gc.weight = 100; 29 | assertFalse(gc.isHardClause()); 30 | gc.weight = 999999999; 31 | assertTrue(gc.isHardClause()); 32 | 33 | assertTrue(Math.abs(gc.cost()-gc.weight)<0.1 ); 34 | gc.weight = -1; 35 | assertTrue(Math.abs(gc.cost()-0)<0.1 ); 36 | gc.nsat = 1; 37 | assertTrue(Math.abs(gc.cost()+gc.weight)<0.1 ); 38 | } 39 | 40 | /** 41 | * Test the relationship between GClause and GAtom. E.g., 42 | * 1) determining whether a GClause object containing a 43 | * GAtom object; 2) replacing atoms in a GClause, etc. 44 | */ 45 | @Test 46 | public final void test_GClause_contain(){ 47 | gc.lits = new int[2]; 48 | gc.lits[0] = -1; 49 | gc.lits[1] = 0; 50 | assertTrue(gc.linkType(1)==-1); 51 | assertTrue(gc.linkType(2)==0); 52 | gc.lits[1] = 2; 53 | assertTrue(gc.linkType(2)==1); 54 | assertTrue(gc.linkType(3)==0); 55 | 56 | gc.lits[0] = 1; 57 | gc.lits[1] = -2; 58 | assertEquals(1, gc.replaceAtomID(1, 3)); 59 | assertEquals(-1, gc.replaceAtomID(2, 4)); 60 | assertEquals(0, gc.replaceAtomID(100, 101)); 61 | assertTrue(gc.linkType(1)==0); 62 | assertTrue(gc.linkType(2)==0); 63 | assertTrue(gc.linkType(3)==1); 64 | assertTrue(gc.linkType(4)==-1); 65 | } 66 | 67 | /** 68 | * Test function transforming GClause object to String 69 | * representation. 70 | */ 71 | @Test 72 | public final void test_GClause_toString() { 73 | 74 | assertEquals("{3,-4} | -1.0", gc.toPGString()); 75 | LinkedHashMap map = new LinkedHashMap(); 76 | GAtom atom3 = new GAtom(3); 77 | atom3.truth = true; 78 | atom3.rep = "atom3"; 79 | GAtom atom4 = new GAtom(4); 80 | atom4.truth = true; 81 | atom4.rep = "atom4"; 82 | map.put(3, atom3); 83 | map.put(4, atom4); 84 | 85 | assertEquals(true, gc.toLongString(map).contains("ViolatedGroundClause0")); 86 | assertEquals(true, gc.toLongString(map).contains("weight=-1.0")); 87 | assertEquals(true, gc.toLongString(map).contains("satisfied=true")); 88 | assertEquals(true, gc.toLongString(map).contains("atom3")); 89 | assertEquals(false, gc.toLongString(map).contains("atom4")); 90 | 91 | assertEquals("-1.0: [3,-4,]", gc.toString()); 92 | 93 | } 94 | 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/GroundingTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.File; 8 | import java.io.FileReader; 9 | import java.util.LinkedHashMap; 10 | 11 | import org.junit.Test; 12 | 13 | import tuffy.db.RDB; 14 | import tuffy.ground.Grounding; 15 | import tuffy.ground.KBMC; 16 | import tuffy.main.Infer; 17 | import tuffy.mln.Clause; 18 | import tuffy.mln.MarkovLogicNetwork; 19 | import tuffy.ra.ConjunctiveQuery; 20 | import tuffy.util.Config; 21 | import tuffy.util.FileMan; 22 | 23 | /** 24 | * Testing class for grounding. 25 | * 26 | */ 27 | public class GroundingTest extends Infer{ 28 | 29 | /** 30 | * Test the function of grounding by counting the number 31 | * of resulting atoms and clauses. 32 | */ 33 | @Test 34 | public void testGrounding() throws Exception{ 35 | 36 | ConjunctiveQuery.clearIndexHistory(); 37 | 38 | Clause.mappingFromID2Const = new LinkedHashMap(); 39 | Clause.mappingFromID2Desc = new LinkedHashMap(); 40 | 41 | 42 | System.out.println("testing grounding"); 43 | MarkovLogicNetwork mln = new MarkovLogicNetwork(); 44 | String prog = "*Friends(person, person)\r\n" + 45 | "Smokes(person)\r\n" + 46 | "Cancer(person)\r\n" + 47 | "0.5 !Smokes(a1) v Cancer(a1)\r\n" + 48 | "0.4 !Friends(a1,a2) v !Smokes(a1) v Smokes(a2)\r\n" + 49 | "0.4 !Friends(a1,a2) v !Smokes(a2) v Smokes(a1)\r\n" + 50 | ""; 51 | FileMan.ensureExistence(Config.dir_tests); 52 | String fprog = Config.dir_tests + "/prog.mln"; 53 | FileMan.writeToFile(fprog, prog); 54 | mln.loadPrograms(new String[]{fprog}); 55 | FileMan.removeFile(fprog); 56 | 57 | String query = "Cancer(x)"; 58 | mln.parseQueryCommaList(query); 59 | 60 | String evid = "Friends(Anna, Bob)\r\n" + 61 | "Friends(Anna, Edward)\r\n" + 62 | "Friends(Anna, Frank)\r\n" + 63 | "Friends(Edward, Frank)\r\n" + 64 | "Friends(Gary, Helen)\r\n" + 65 | "!Friends(Gary, Frank)\r\n" + 66 | "Smokes(Anna)\r\n" + 67 | "Smokes(Edward)\r\n" + 68 | ""; 69 | String fevid = Config.dir_tests + "/evidence.db"; 70 | FileMan.writeToFile(fevid, evid); 71 | RDB db = RDB.getRDBbyConfig(); 72 | db.resetSchema(Config.db_schema); 73 | mln.prepareDB(db); 74 | mln.loadEvidences(new String[]{fevid}); 75 | FileMan.removeFile(fevid); 76 | 77 | mln.materializeTables(); 78 | 79 | KBMC kbmc = new KBMC(mln); 80 | kbmc.run(); 81 | Grounding grounding = new Grounding(mln); 82 | grounding.constructMRF(); 83 | 84 | assertEquals(6, db.countTuples(mln.relClauses)); 85 | assertEquals(6, grounding.getNumAtoms()); 86 | assertEquals(6, grounding.getNumClauses()); 87 | 88 | assertTrue(mln.cleanUp()); 89 | FileMan.removeDirectory(new File(Config.dir_tests)); 90 | } 91 | 92 | public final String getSimpleInferenceResult() throws Exception{ 93 | 94 | BufferedReader br = new BufferedReader(new FileReader("testOutput.txt")); 95 | 96 | String rs = ""; 97 | String tmp; 98 | 99 | while((tmp = br.readLine())!=null){ 100 | rs += tmp; 101 | } 102 | 103 | br.close(); 104 | 105 | return rs; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/LiteralTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.util.ArrayList; 6 | import java.util.LinkedHashMap; 7 | 8 | 9 | import org.junit.Test; 10 | 11 | import tuffy.mln.Literal; 12 | import tuffy.mln.Predicate; 13 | import tuffy.mln.Term; 14 | import tuffy.mln.Tuple; 15 | import tuffy.mln.Type; 16 | import tuffy.util.Config; 17 | 18 | /** 19 | * Testing class for {@link Literal} class. 20 | * 21 | */ 22 | public class LiteralTest { 23 | 24 | @Test 25 | public final void test_scopeLit() { 26 | /* 27 | Type t = new Type("testType1"); 28 | t.addConstant(1); 29 | t.addConstant(2); 30 | 31 | Predicate p = new Predicate(null, "pred", false); 32 | p.appendArgument(t); 33 | Literal l = new Literal(p, false);*/ 34 | 35 | } 36 | 37 | 38 | /** 39 | * Test functions of transforming Literal object to String 40 | * representation. Also test the relationship between 41 | * Literal and Term. 42 | */ 43 | @Test 44 | public final void test_toString_and_getVars() { 45 | 46 | Type t = new Type("testType1"); 47 | t.addConstant(1); 48 | t.addConstant(2); 49 | 50 | Predicate p = new Predicate(null, "pred", false); 51 | p.appendArgument(t); 52 | p.appendArgument(t); 53 | 54 | Literal l = new Literal(p, false); 55 | l.appendTerm(new Term(111)); 56 | l.appendTerm(new Term("variable")); 57 | 58 | assertEquals("!pred(111, variable)",l.toString()); 59 | 60 | assertEquals(true, l.getVars().contains("variable")); 61 | 62 | } 63 | 64 | /** 65 | * Test isSameAs function of Literal. 66 | */ 67 | @Test 68 | public final void test_isSameAs() { 69 | Type t1 = new Type("testType1"); 70 | t1.addConstant(1); 71 | t1.addConstant(2); 72 | 73 | Predicate p1 = new Predicate(null, "pred1", false); 74 | p1.appendArgument(t1); 75 | p1.appendArgument(t1); 76 | 77 | Type t2 = new Type("testType2"); 78 | t2.addConstant(1); 79 | t2.addConstant(2); 80 | 81 | Predicate p2 = new Predicate(null, "pred2", false); 82 | p2.appendArgument(t2); 83 | p2.appendArgument(t2); 84 | 85 | Literal l1 = new Literal(p1, false); 86 | l1.appendTerm(new Term(1)); 87 | l1.appendTerm(new Term("variable")); 88 | 89 | Literal l2 = new Literal(p2, false); 90 | l1.appendTerm(new Term(1)); 91 | l1.appendTerm(new Term("variable")); 92 | 93 | assertEquals(false, l2.isSameAs(l1)); 94 | 95 | Literal l3 = new Literal(p1, false); 96 | l3.appendTerm(new Term(2)); 97 | l3.appendTerm(new Term("variable")); 98 | 99 | assertEquals(false, l3.isSameAs(l1)); 100 | 101 | Literal l4 = new Literal(p1, false); 102 | l4.appendTerm(new Term("w")); 103 | l4.appendTerm(new Term("variable")); 104 | 105 | assertEquals(false, l4.isSameAs(l1)); 106 | 107 | assertEquals(true, l1.isSameAs(l1)); 108 | 109 | } 110 | 111 | /** 112 | * Test function of getting the MGU (most general unification) 113 | * of two literals. Also test the function of substitution. 114 | */ 115 | @Test 116 | public final void test_mostGeneralUnification_and_substitute_and_toTuple(){ 117 | Type t = new Type("testType1"); 118 | t.addConstant(1); 119 | t.addConstant(2); 120 | 121 | Predicate p = new Predicate(null, "pred", false); 122 | p.appendArgument(t); 123 | p.appendArgument(t); 124 | 125 | Literal l = new Literal(p, false); 126 | l.appendTerm(new Term(1)); 127 | l.appendTerm(new Term("variable")); 128 | l.appendTerm(new Term(3)); 129 | 130 | ArrayList list = new ArrayList(); 131 | list.add(1); 132 | list.add(2); 133 | list.add(3); 134 | Tuple tu = new Tuple(list); 135 | LinkedHashMap mgu = l.mostGeneralUnification(tu); 136 | assertEquals(true, mgu.containsKey("variable")); 137 | assertFalse(Config.constants_as_raw_string); 138 | assertEquals(2, mgu.get("variable").constant()); 139 | assertEquals(2, l.substitute(mgu).getTerms().get(1).constant()); 140 | assertEquals(-1, l.toTuple().get(1)); 141 | 142 | list = new ArrayList(); 143 | list.add(2); 144 | list.add(2); 145 | list.add(3); 146 | tu = new Tuple(list); 147 | mgu = l.mostGeneralUnification(tu); 148 | assertEquals(null, mgu); 149 | 150 | list = new ArrayList(); 151 | list.add(-1); 152 | list.add(2); 153 | list.add(-1); 154 | tu = new Tuple(list); 155 | mgu = l.mostGeneralUnification(tu); 156 | assertEquals(null, mgu); 157 | 158 | list = new ArrayList(); 159 | list.add(-1); 160 | list.add(1); 161 | list.add(3); 162 | tu = new Tuple(list); 163 | mgu = l.mostGeneralUnification(tu); 164 | assertEquals(true, mgu.containsKey("variable")); 165 | assertEquals(1, mgu.get("variable").constant()); 166 | 167 | l = new Literal(p, false); 168 | l.appendTerm(new Term(1)); 169 | l.appendTerm(new Term("variable")); 170 | l.appendTerm(new Term("variable")); 171 | 172 | list = new ArrayList(); 173 | list.add(1); 174 | list.add(2); 175 | list.add(3); 176 | tu = new Tuple(list); 177 | mgu = l.mostGeneralUnification(tu); 178 | assertEquals(null, mgu); 179 | 180 | l = new Literal(p, false); 181 | l.appendTerm(new Term("variable")); 182 | l.appendTerm(new Term(5)); 183 | l.appendTerm(new Term("variable")); 184 | 185 | list = new ArrayList(); 186 | list.add(1); 187 | list.add(-1); 188 | list.add(-1); 189 | tu = new Tuple(list); 190 | mgu = l.mostGeneralUnification(tu); 191 | assertEquals(null, mgu); 192 | 193 | 194 | } 195 | 196 | } 197 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/PredicateTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.sql.PreparedStatement; 6 | import java.sql.ResultSet; 7 | import java.util.ArrayList; 8 | 9 | 10 | import org.junit.Test; 11 | 12 | import tuffy.db.RDB; 13 | import tuffy.mln.Atom; 14 | import tuffy.mln.Clause; 15 | import tuffy.mln.MarkovLogicNetwork; 16 | import tuffy.mln.Predicate; 17 | import tuffy.mln.Type; 18 | import tuffy.util.Config; 19 | 20 | 21 | /** 22 | * Testing class for {@link Predicate} object. 23 | * 24 | */ 25 | public class PredicateTest { 26 | 27 | /** 28 | * Test the function setAllQuery(). 29 | */ 30 | @Test 31 | public final void testSetAllQuery() { 32 | Predicate p = new Predicate(null, "dummy", true); 33 | assertTrue(p.getQueryAtoms().isEmpty()); 34 | p.appendArgument(new Type("type1")); 35 | p.appendArgument(new Type("type2")); 36 | p.setAllQuery(); 37 | assertFalse(p.getQueryAtoms().isEmpty()); 38 | } 39 | 40 | /** 41 | * Test closed-world-related functions. 42 | */ 43 | @Test 44 | public final void testSetClosedWorld() { 45 | Predicate p = new Predicate(null, "dummy", false); 46 | assertFalse(p.isClosedWorld()); 47 | p.setClosedWorld(true); 48 | assertTrue(p.isClosedWorld()); 49 | p.setClosedWorld(false); 50 | assertFalse(p.isClosedWorld()); 51 | } 52 | 53 | /** 54 | * Test argument-related functions. 55 | */ 56 | @Test 57 | public final void testGetArgs() { 58 | Predicate p = new Predicate(null, "dummy", false); 59 | assertTrue(p.getArgs().isEmpty()); 60 | Type type = new Type("xx"); 61 | p.appendArgument(type); 62 | assertEquals(1, p.getArgs().size()); 63 | assertEquals(type, p.getTypeAt(0)); 64 | } 65 | 66 | /** 67 | * Test ID-related functions. 68 | */ 69 | @Test 70 | public final void testSetID() { 71 | Predicate p = new Predicate(null, "dummy", true); 72 | assertFalse(774 == p.getID()); 73 | p.setID(774); 74 | assertTrue(774 == p.getID()); 75 | assertTrue(p.noNeedToGround()); 76 | } 77 | 78 | /** 79 | * Test functions of grounding a predicate and store 80 | * the resulting atoms to database table. 81 | */ 82 | @Test 83 | public final void testGroundAndStoreAtom() throws Exception { 84 | MarkovLogicNetwork mln = new MarkovLogicNetwork(); 85 | Predicate p = new Predicate(mln, "dummy", false); 86 | mln.registerPred(p); 87 | 88 | //Config.test.flushTestConfiguration(); 89 | RDB db = RDB.getRDBbyConfig(); 90 | db.resetSchema(Config.db_schema); 91 | Type type = new Type("xx"); 92 | type.addConstant(1); 93 | type.addConstant(2); 94 | type.addConstant(3); 95 | type.storeConstantList(db); 96 | p.appendArgument(type); 97 | p.appendArgument(type); 98 | p.prepareDB(db); 99 | assertEquals(0, db.countTuples(p.getRelName())); 100 | ArrayList list = new ArrayList(); 101 | list.add(2); 102 | list.add(3); 103 | Atom atom = new Atom(p, list, true); 104 | p.groundAndStoreAtom(atom); 105 | assertEquals(1, db.countTuples(p.getRelName())); 106 | list = new ArrayList(); 107 | list.add(3); 108 | list.add(-1); 109 | atom = new Atom(p, list, true); 110 | p.groundAndStoreAtom(atom); 111 | assertEquals(4, db.countTuples(p.getRelName())); 112 | p.closeFiles(); 113 | 114 | list = new ArrayList(); 115 | list.add(-1); 116 | list.add(-1); 117 | atom = new Atom(p, list, true); 118 | p.groundAndStoreAtom(atom); 119 | assertEquals(6, db.countTuples(p.getRelName())); 120 | p.closeFiles(); 121 | 122 | 123 | list = new ArrayList(); 124 | list.add(-1); 125 | list.add(-1); 126 | atom = new Atom(p, list, true); 127 | 128 | atom.type = Atom.AtomType.QUERY; 129 | p.groundAndStoreAtom(atom); 130 | assertEquals(6, db.countTuples(p.getRelName())); 131 | 132 | PreparedStatement ps = db.getPrepareStatement("SELECT COUNT(*) AS CT FROM " + 133 | p.getRelName() + " WHERE club = 1 OR club = 3"); 134 | ps.execute(); 135 | ResultSet rss = ps.getResultSet(); 136 | rss.next(); 137 | int rs = rss.getInt("CT"); 138 | assertEquals(3, rs); 139 | 140 | //TODO: CHANGE FOR ``SAME'' 141 | //test getPredicateByName 142 | // assertTrue(mln.getPredByName("same")!=null); 143 | 144 | } 145 | 146 | /** 147 | * Test functions of marking some atoms as evidence. 148 | */ 149 | @Test 150 | public final void testEvidence() { 151 | /* 152 | MarkovLogicNetwork mln = new MarkovLogicNetwork(); 153 | Predicate p = new Predicate(mln, "dummy", false); 154 | mln.registerPred(p); 155 | RDB db = RDB.getRDBbyConfig(); 156 | db.resetSchema("tuffy_test"); 157 | Type type = new Type("xx"); 158 | type.addConstant(1); 159 | type.addConstant(2); 160 | type.addConstant(3); 161 | type.storeConstantList(db); 162 | p.appendArgument(type); 163 | p.appendArgument(type); 164 | p.prepareDB(db); 165 | assertEquals(0, db.countTuples(p.getRelName())); 166 | ArrayList list = new ArrayList(); 167 | list.add(1); 168 | list.add(3); 169 | Atom atom = new Atom(p, list, false); 170 | p.addEvidence(atom); 171 | p.flushEvidence(); 172 | assertEquals(1, db.countTuples(p.getRelName())); 173 | p.closeFiles(); 174 | */ 175 | } 176 | 177 | /** 178 | * Test functions of marking some atoms as query. 179 | */ 180 | @Test 181 | public final void testStoreQueries() { 182 | MarkovLogicNetwork mln = new MarkovLogicNetwork(); 183 | Predicate p = new Predicate(mln, "dummy", false); 184 | mln.registerPred(p); 185 | RDB db = RDB.getRDBbyConfig(); 186 | db.resetSchema("tuffy_test"); 187 | Type type = new Type("xx"); 188 | type.addConstant(1); 189 | type.addConstant(2); 190 | type.addConstant(3); 191 | type.storeConstantList(db); 192 | p.appendArgument(type); 193 | p.appendArgument(type); 194 | p.prepareDB(db); 195 | assertEquals(0, db.countTuples(p.getRelName())); 196 | ArrayList list = new ArrayList(); 197 | list.add(-1); 198 | list.add(3); 199 | Atom atom = new Atom(p, list, false); 200 | p.addQuery(atom); 201 | p.storeQueries(); 202 | assertEquals(3, db.countTuples(p.getRelName())); 203 | p.closeFiles(); 204 | } 205 | 206 | /** 207 | * Test functions of determining whether there are query atoms 208 | * belonging to this predication. 209 | */ 210 | @Test 211 | public final void testHasQuery() { 212 | Predicate p = new Predicate(null, "dummy", true); 213 | assertFalse(p.hasQuery()); 214 | p.setAllQuery(); 215 | assertTrue(p.hasQuery()); 216 | } 217 | 218 | /** 219 | * Test arity-related functions of Predicate. 220 | */ 221 | @Test 222 | public final void testArity() { 223 | Predicate p = new Predicate(null, "dummy", false); 224 | assertEquals(0, p.arity()); 225 | p.appendArgument(new Type("imatype")); 226 | assertEquals(1, p.arity()); 227 | } 228 | 229 | /** 230 | * Test functions of building clause-predicate relationships. 231 | */ 232 | @Test 233 | public final void testAddRelatedClause() { 234 | Predicate p = new Predicate(null, "dummy", false); 235 | assertEquals(0, p.getRelatedClauses().size()); 236 | p.addRelatedClause(new Clause()); 237 | assertEquals(1, p.getRelatedClauses().size()); 238 | } 239 | 240 | } 241 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/TermTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.util.ArrayList; 6 | 7 | import org.junit.Test; 8 | 9 | import tuffy.mln.Term; 10 | import tuffy.mln.Tuple; 11 | 12 | /** 13 | * Testing class for {@link Term} class. 14 | * 15 | */ 16 | public class TermTest { 17 | 18 | /** 19 | * Test functions of transforming Term object to String 20 | * representation. 21 | */ 22 | @Test 23 | public final void test_toString() { 24 | Term t1 = new Term("testT"); 25 | assertEquals(true, t1.isVariable()); 26 | 27 | Term t2 = new Term(1000); 28 | assertEquals(true, t2.isConstant()); 29 | 30 | assertEquals("testT", t1.toString()); 31 | assertEquals("1000", t2.toString()); 32 | 33 | } 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/TupleTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.util.ArrayList; 6 | 7 | import org.junit.Test; 8 | 9 | import tuffy.mln.Tuple; 10 | 11 | /** 12 | * Testing class for {@link Tuple} object. 13 | * 14 | */ 15 | public class TupleTest { 16 | 17 | /** 18 | * Test relationships between tuple and term ID. 19 | */ 20 | @Test 21 | public final void test_get() { 22 | 23 | ArrayList al = new ArrayList(); 24 | al.add(1); 25 | al.add(-1); 26 | al.add(1212); 27 | 28 | Tuple t = new Tuple(al); 29 | 30 | assertEquals(1, t.get(0)); 31 | assertEquals(-1, t.get(1)); 32 | assertEquals(1212, t.get(2)); 33 | } 34 | 35 | /** 36 | * Test subsume functions of two tuple. 37 | */ 38 | @Test 39 | public final void test_subsume() { 40 | ArrayList al1 = new ArrayList(); 41 | al1.add(-1); 42 | al1.add(-2); 43 | al1.add(-1); 44 | al1.add(1212); 45 | Tuple t1 = new Tuple(al1); 46 | 47 | ArrayList al2 = new ArrayList(); 48 | al2.add(12); 49 | al2.add(-1000); 50 | al2.add(12); 51 | al2.add(1212); 52 | Tuple t2 = new Tuple(al2); 53 | 54 | ArrayList al3 = new ArrayList(); 55 | al3.add(11); 56 | al3.add(-1); 57 | al3.add(13); 58 | al3.add(1212); 59 | Tuple t3 = new Tuple(al3); 60 | 61 | ArrayList al4 = new ArrayList(); 62 | al4.add(5); 63 | al4.add(-1); 64 | al4.add(-2); 65 | al4.add(-1); 66 | al4.add(1212); 67 | Tuple t4 = new Tuple(al4); 68 | 69 | ArrayList al5 = new ArrayList(); 70 | al5.add(-1); 71 | al5.add(-2); 72 | al5.add(-1); 73 | al5.add(1); 74 | Tuple t5 = new Tuple(al5); 75 | 76 | assertEquals(true, t1.subsumes(t2)); 77 | assertEquals(false, t1.subsumes(t3)); 78 | assertEquals(false, t1.subsumes(t4)); 79 | assertEquals(false, t1.subsumes(t5)); 80 | 81 | } 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/tuffy/test/TypeTest.java: -------------------------------------------------------------------------------- 1 | package tuffy.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.sql.PreparedStatement; 6 | import java.sql.ResultSet; 7 | 8 | import org.junit.Test; 9 | 10 | import tuffy.db.RDB; 11 | import tuffy.mln.Type; 12 | import tuffy.util.Config; 13 | 14 | 15 | import java.util.Random; 16 | 17 | /** 18 | * Testing class of {@link Type} object. 19 | * 20 | */ 21 | public class TypeTest { 22 | 23 | public static Random rg = new Random(1); 24 | 25 | /** 26 | * Test functions of building and querying the constant 27 | * doamin of Type. 28 | */ 29 | @Test 30 | public final void test_AddConstant_and_Contains() { 31 | 32 | Type t = new Type("testType1"); 33 | 34 | int[] isContainingIndex = new int[10000]; 35 | for(int i=0;i 2 | 3 | Test Package 4 | 5 | 6 | 7 | This package includes testing codes for tuffy. These tests are grouped into two 8 | categories. 9 | 10 |

Unit Testing

11 | 12 | Testings in this group intend to test the basic data structure of Tuffy. 13 | In Tuffy, the whole system is built upon classes referring to logic or 14 | mathematical objects, e.g., Predicate, Atom, etc. All these objects are 15 | associated with several operations, e.g., a Clause object can ``absorb'' 16 | another Clause object with the same pattern. Testings in this category 17 | try to make sure such functionality works consistently with their definition 18 | and designing goals. 19 | 20 | Following classes belong to this category: 21 | 22 |
    23 |
  • AtomTest 24 |
  • ClauseTest 25 |
  • ConfigTest 26 |
  • GAtomTest 27 |
  • GClauseTest 28 |
  • LiteralTest 29 |
  • ParsingLoadingTest 30 |
  • PredicateTest 31 |
  • TermTest 32 |
  • TupleTest 33 |
  • TypeTest 34 |
35 | 36 |

System Testing

37 | 38 | Testings in this group intend to test the functionality of the whole Tuffy system. 39 | While Unit Testing tested the blocks of building Tuffy, testings in this group 40 | make them together. Two functions of Tuffy are tested here: 41 | 42 |
    43 |
  • Inference: Given MLN program, evidence and query, return the most possible 44 | truth assignment for queries. 45 |
  • Learning: Given MLN program, evidence (w/o training data) and query, return the 46 | most possible clause weights. 47 |
48 | 49 | Following classes belong to this category: 50 | 51 |
    52 |
  • ClauseTest 53 |
  • GroundingTest 54 |
  • LearnerTest 55 |
56 | 57 | 58 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/BatMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | public class BatMan { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/BitSetDoublePair.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.BitSet; 4 | 5 | public class BitSetDoublePair implements Comparable{ 6 | 7 | public BitSet bitset; 8 | public Double doub; 9 | 10 | public BitSetDoublePair(BitSet _bitset, Double _double){ 11 | bitset = _bitset; 12 | doub = _double; 13 | } 14 | 15 | @Override 16 | public int compareTo(Object o) { 17 | if(this.doub - ((BitSetDoublePair) o).doub > 0){ 18 | return 1; 19 | }else{ 20 | return -1; 21 | } 22 | } 23 | 24 | public String toString(){ 25 | return doub + ": " + bitset; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/BitSetIntPair.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.BitSet; 4 | 5 | 6 | public class BitSetIntPair implements Comparable{ 7 | 8 | public BitSet bitset; 9 | public Integer integer; 10 | 11 | public BitSetIntPair(BitSet _bitset, Integer _integer){ 12 | bitset = _bitset; 13 | integer = _integer; 14 | } 15 | 16 | @Override 17 | public int compareTo(Object o) { 18 | return this.integer - ((BitSetIntPair) o).integer; 19 | } 20 | 21 | public String toString(){ 22 | return integer + ": " + bitset; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/BoundHashList.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.LinkedHashSet; 4 | import java.util.LinkedList; 5 | 6 | public class BoundHashList { 7 | LinkedList list = new LinkedList(); 8 | LinkedHashSet set = new LinkedHashSet(); 9 | 10 | private int bound = Integer.MAX_VALUE; 11 | 12 | public boolean contains(T e){ 13 | return set.contains(e); 14 | } 15 | 16 | public BoundHashList(int maxSize){ 17 | bound = maxSize; 18 | } 19 | 20 | public boolean add(T e){ 21 | if(set.contains(e)) return false; 22 | if(list.size() >= bound){ 23 | set.remove(list.removeFirst()); 24 | } 25 | list.addLast(e); 26 | set.add(e); 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/DebugMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | import java.util.Scanner; 3 | 4 | /** 5 | * Container of methods for debugging purposes. 6 | */ 7 | public class DebugMan { 8 | 9 | private static StringBuilder log = new StringBuilder(); 10 | 11 | public static void log(String s){ 12 | log.append(s); 13 | } 14 | 15 | public static String getLog(){ 16 | return log.toString(); 17 | } 18 | 19 | public static void pause() { 20 | System.out.println("\nPress enter to continue..."); 21 | Scanner in = new Scanner(System.in); 22 | in.nextLine(); 23 | } 24 | 25 | public static boolean runningInWindows(){ 26 | String os = System.getProperty("os.name").toLowerCase(); 27 | return os.contains("win"); 28 | } 29 | 30 | private static final Runtime s_runtime = Runtime.getRuntime (); 31 | public static void runGC() throws Exception 32 | { 33 | // It helps to call Runtime.gc() 34 | // using several method calls: 35 | for (int r = 0; r < 4; ++ r) _runGC (); 36 | } 37 | private static void _runGC () throws Exception 38 | { 39 | long usedMem1 = usedMemoryp (), usedMem2 = Long.MAX_VALUE; 40 | for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++ i) 41 | { 42 | s_runtime.runFinalization (); 43 | s_runtime.gc (); 44 | Thread.yield(); 45 | 46 | usedMem2 = usedMem1; 47 | usedMem1 = usedMemoryp (); 48 | } 49 | } 50 | 51 | private static long usedMemoryp () 52 | { 53 | return s_runtime.totalMemory () - s_runtime.freeMemory (); 54 | } 55 | 56 | public static long usedMemory(){ 57 | try{ 58 | runGC(); 59 | }catch(Exception e){ 60 | System.err.println(e.getMessage()); 61 | } 62 | long mem0 = Runtime.getRuntime().totalMemory() - 63 | Runtime.getRuntime().freeMemory(); 64 | return mem0; 65 | } 66 | 67 | static private long baseMem = 0; 68 | public static void checkBaseMem(){ 69 | baseMem = usedMemory(); 70 | } 71 | 72 | public static long getBaseMem(){ 73 | return baseMem; 74 | } 75 | 76 | 77 | static private long peakMem = 0; 78 | public static void checkPeakMem(){ 79 | long mem = usedMemory(); 80 | if(mem > peakMem){ 81 | peakMem = mem; 82 | } 83 | } 84 | 85 | public static long getPeakMem(){ 86 | return peakMem; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/DeterministicMapHelper.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | public class DeterministicMapHelper { 6 | public static void putIfAbsent(LinkedHashMap map, Object k, Object v) { 7 | if (!map.containsKey(k)) { 8 | map.put(k, v); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/Enumerator.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | /** 4 | * A Enumerator is used to enumerate exponentially many configurations. 5 | * @author czhang 6 | * 7 | */ 8 | public class Enumerator { 9 | 10 | int[] upperBounds; 11 | int[] currentState; 12 | 13 | /** 14 | * Enumerate 2**n worlds. 15 | * @param n 16 | */ 17 | public Enumerator(int n){ 18 | upperBounds = new int[n]; 19 | currentState = new int[n]; 20 | for(int i=0;i getLines(String filename){ 101 | try { 102 | FileReader reader = new FileReader(filename); 103 | BufferedReader lreader = new BufferedReader(reader); 104 | String line = lreader.readLine(); 105 | ArrayList lines = new ArrayList(); 106 | while(line != null){ 107 | lines.add(line); 108 | line = lreader.readLine(); 109 | } 110 | lreader.close(); 111 | return lines; 112 | }catch(IOException e) { 113 | ExceptionMan.handle(e); 114 | } 115 | return null; 116 | } 117 | 118 | /** 119 | * Reads content from a text file. 120 | */ 121 | public static String getTextContent(String filename){ 122 | return StringMan.join("\n", getLines(filename)); 123 | } 124 | 125 | /** 126 | * Removes a directory, even if it's NOT empty! 127 | * @return true on success 128 | */ 129 | static public boolean removeDirectory(File path) { 130 | if( path.exists() ) { 131 | File[] files = path.listFiles(); 132 | for(int i=0; i fg.lastModified()){ 177 | picked = f; 178 | }else{ 179 | picked = g; 180 | } 181 | UIMan.warn("Both regular and gzip'ed versions of this file exist; will use the newer one: " + picked); 182 | return picked; 183 | }else if(exists(g)){ 184 | return g; 185 | }else{ 186 | return f; 187 | } 188 | } 189 | } 190 | 191 | public static boolean exists(String f){ 192 | File path = new File(f); 193 | return path.exists(); 194 | } 195 | 196 | /** 197 | * Removes a file. 198 | */ 199 | public static boolean removeFile(String file){ 200 | File f = new File(file); 201 | return f.delete(); 202 | } 203 | 204 | } 205 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/HashArray.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedHashMap; 5 | import java.util.Random; 6 | 7 | public class HashArray { 8 | ArrayList list = new ArrayList(); 9 | LinkedHashMap indices = new LinkedHashMap(); 10 | Random rand = SeededRandom.getInstance(); 11 | 12 | public int size = 0; 13 | 14 | public ArrayList getList(){ 15 | return list; 16 | } 17 | 18 | public T getRandomElement(){ 19 | return list.get(rand.nextInt(list.size())); 20 | } 21 | 22 | public boolean contains(T e){ 23 | return indices.containsKey(e); 24 | } 25 | 26 | public void clear(){ 27 | list.clear(); 28 | indices.clear(); 29 | size = 0; 30 | } 31 | 32 | public boolean isEmpty(){ 33 | return list.isEmpty(); 34 | } 35 | 36 | public void add(T e){ 37 | if(indices.containsKey(e)) return; 38 | list.add(e); 39 | indices.put(e, list.size() - 1); 40 | size ++; 41 | } 42 | 43 | public void removeIdx(int i){ 44 | int ss = list.size(); 45 | if(i < 0 || i >= ss) return; 46 | indices.remove(list.get(i)); 47 | if(i == ss-1){ 48 | list.remove(i); 49 | }else{ 50 | T last = list.get(ss-1); 51 | indices.put(last, i); 52 | list.set(i, last); 53 | list.remove(ss-1); 54 | } 55 | size --; 56 | } 57 | 58 | public void removeObj(T e){ 59 | if(!indices.containsKey(e)) return; 60 | int i = indices.get(e); 61 | removeIdx(i); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/IronMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | public class IronMan { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/MathMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | public class MathMan { 4 | public static int prorate(int total, double ratio){ 5 | return (int)(total * ratio); 6 | } 7 | 8 | public static double getLogOddsWeight(double prob){ 9 | if(prob < 0 || prob > 1) return 0; 10 | if(prob == 0) return -Config.hard_weight; 11 | if(prob == 1) return Config.hard_weight; 12 | return Math.log(prob/(1-prob)); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/PlotMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class PlotMan { 6 | 7 | public static class TCPair{ 8 | public double time, cost; 9 | public TCPair(double t, double c){ 10 | time = t; 11 | cost = c; 12 | } 13 | 14 | public String toString(){ 15 | return time + "\t" + cost; 16 | } 17 | 18 | public static TCPair parse(String line){ 19 | String[] parts = line.trim().split("\t"); 20 | if(parts.length != 2) return null; 21 | double t = Double.parseDouble(parts[0]); 22 | double c = Double.parseDouble(parts[1]); 23 | return new TCPair(t,c); 24 | } 25 | } 26 | 27 | public ArrayList input(String fin){ 28 | System.out.println("reading..."); 29 | ArrayList lines = FileMan.getLines(fin); 30 | ArrayList out = new ArrayList(); 31 | for(String line : lines){ 32 | TCPair p = TCPair.parse(line); 33 | if(p != null) out.add(p); 34 | } 35 | System.out.println("#points = " + out.size()); 36 | return out; 37 | } 38 | 39 | public void output(ArrayList list, String fout){ 40 | System.out.println("writing..."); 41 | StringBuilder sb = new StringBuilder(); 42 | for(TCPair p : list){ 43 | sb.append(p + "\n"); 44 | } 45 | FileMan.writeToFile(fout, sb.toString()); 46 | } 47 | 48 | public ArrayList filter(ArrayList list){ 49 | System.out.println("filtering..."); 50 | double granu = 100; 51 | if(list.size() < 20) return list; 52 | ArrayList out = new ArrayList(); 53 | TCPair first = list.get(0); 54 | TCPair last = list.get(list.size()-1); 55 | double mint = (last.time - first.time)/granu; 56 | double minc = (first.cost - last.cost)/granu; 57 | 58 | out.add(first); 59 | TCPair prev = first; 60 | for(int i=1; i= mint || 63 | prev.cost - cur.cost >= minc){ 64 | out.add(cur); 65 | prev = cur; 66 | } 67 | } 68 | out.add(last); 69 | System.out.println("#points = " + out.size()); 70 | 71 | return out; 72 | } 73 | 74 | public void spit(int n, String fout){ 75 | StringBuilder sb = new StringBuilder(); 76 | for(int i=1; i<=n; i++){ 77 | sb.append("pub(P" + i + ")\n"); 78 | } 79 | FileMan.writeToFile(fout, sb.toString()); 80 | } 81 | 82 | public static void main(String[] args) { 83 | String loc = "/sandbox/exp/"; 84 | String fin = loc + "trace.txt"; 85 | String fout = loc + "points.txt"; 86 | PlotMan man = new PlotMan(); 87 | man.spit(1000, "/sandbox/bench/wam/evidence.db"); 88 | man.output(man.filter(man.input(fin)), fout); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/ProbMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.Random; 4 | 5 | public class ProbMan { 6 | private static Random rand = SeededRandom.getInstance(); 7 | 8 | public static void resetStaticVars() { 9 | rand = SeededRandom.getInstance(); 10 | } 11 | 12 | public static boolean testChance(double prob){ 13 | return rand.nextDouble() < prob; 14 | } 15 | 16 | public static double nextDouble(){ 17 | return rand.nextDouble(); 18 | } 19 | 20 | public static boolean nextBoolean(){ 21 | return rand.nextBoolean(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/SeededRandom.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.Random; 4 | 5 | public class SeededRandom { 6 | private static Random instance = null; 7 | 8 | protected SeededRandom() { 9 | // Exists only to defeat instantiation. 10 | } 11 | 12 | public static void reset() { 13 | instance = null; 14 | } 15 | 16 | public static Random getInstance() { 17 | if (instance == null) { 18 | if (Config.seed != 0) { 19 | instance = new Random(Config.seed); 20 | } else { 21 | instance = new Random(); 22 | } 23 | } 24 | return instance; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/Settings.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedHashMap; 5 | import java.util.Map; 6 | 7 | public class Settings { 8 | private LinkedHashMap map = new LinkedHashMap(); 9 | 10 | public Settings(){ 11 | 12 | } 13 | 14 | public String toString(){ 15 | ArrayList lines = new ArrayList(); 16 | for(String k : map.keySet()){ 17 | lines.add(" " + k + ": " + map.get(k).toString()); 18 | } 19 | return StringMan.join("\n", lines); 20 | } 21 | 22 | public Settings(Map map){ 23 | this.map.putAll(map); 24 | } 25 | 26 | public void put(String k, Object v){ 27 | map.put(k, v); 28 | } 29 | 30 | public boolean hasKey(String k){ 31 | return map.containsKey(k); 32 | } 33 | 34 | public Object get(String k){ 35 | return map.get(k); 36 | } 37 | 38 | public Integer getInt(String k){ 39 | return (Integer)(map.get(k)); 40 | } 41 | 42 | public Double getDouble(String k){ 43 | return (Double)(map.get(k)); 44 | } 45 | 46 | public String getString(String k){ 47 | return (String)(map.get(k)); 48 | } 49 | 50 | public Boolean getBool(String k){ 51 | return (Boolean)(map.get(k)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/SpiderMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | public class SpiderMan { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/Stats.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | public class Stats { 4 | public static int numberUnits = 0; 5 | public static int numberGroundAtoms = 0; 6 | public static int numberGroundClauses = 0; 7 | public static int numberSamplesAtTimeout = 0; 8 | public static int numberClausesAtTimeout = 0; 9 | public static double glucoseTimeMs = 0; 10 | public static double javaUPGroundingTimeMs = 0; 11 | public static int totalUnitsDuringIUP = 0; 12 | public static String latestCBuffer = ""; 13 | public static int mcsatStepsWhereSampleSatFails = 0; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/StringMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.apache.commons.lang3.StringEscapeUtils; 7 | 8 | import tuffy.db.SQLMan; 9 | 10 | /** 11 | * Container of string related utilities. 12 | */ 13 | public class StringMan { 14 | 15 | private static int uniqVar = 1; 16 | 17 | public static String getUniqVarName(){ 18 | return "uniqvar" + (uniqVar++); 19 | } 20 | 21 | public static String escapeJavaString(String s){ 22 | return StringEscapeUtils.escapeJava(s); 23 | } 24 | 25 | public static String quoteJavaString(String s){ 26 | return "\"" + StringEscapeUtils.escapeJava(s) + "\""; 27 | } 28 | 29 | /** 30 | * Gets a string with all zeros. 31 | * @param length 32 | * @return 33 | */ 34 | public static String zeros(int length){ 35 | StringBuilder sb = new StringBuilder(); 36 | for(int i=0;i parts) { 50 | StringBuilder sb = new StringBuilder(""); 51 | for(int i=0; i parts) { 59 | StringBuilder sb = new StringBuilder(""); 60 | for(int i=0; i parts) { 68 | StringBuilder sb = new StringBuilder(""); 69 | for(int i=0; i parts) { 83 | return join(", ", parts); 84 | } 85 | 86 | public static String commaList(List parts) { 87 | return join(", ", parts); 88 | } 89 | 90 | 91 | /** 92 | * Concatenates multiple strings with commas, and then 93 | * surrounds the result with a pair of parentheses. 94 | * 95 | * @param ts substrings to be concatenated 96 | * @return the resulting string 97 | */ 98 | public static String commaListParen(ArrayList ts) { 99 | return "(" + commaList(ts) + ")"; 100 | } 101 | 102 | public static String repeat(String str, int repeat) { 103 | if (str == null) { 104 | return null; 105 | } 106 | if (repeat <= 0) { 107 | return ""; 108 | } 109 | int inputLength = str.length(); 110 | if (repeat == 1 || inputLength == 0) { 111 | return str; 112 | } 113 | int outputLength = inputLength * repeat; 114 | switch (inputLength) { 115 | case 1 : 116 | char ch = str.charAt(0); 117 | char[] output1 = new char[outputLength]; 118 | for (int i = repeat - 1; i >= 0; i--) { 119 | output1[i] = ch; 120 | } 121 | return new String(output1); 122 | case 2 : 123 | char ch0 = str.charAt(0); 124 | char ch1 = str.charAt(1); 125 | char[] output2 = new char[outputLength]; 126 | for (int i = repeat * 2 - 2; i >= 0; i--, i--) { 127 | output2[i] = ch0; 128 | output2[i + 1] = ch1; 129 | } 130 | return new String(output2); 131 | default : 132 | StringBuilder buf = new StringBuilder(outputLength); 133 | for (int i = 0; i < repeat; i++) { 134 | buf.append(str); 135 | } 136 | return buf.toString(); 137 | } 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/SuperMan.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | public class SuperMan { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/Timer.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | import java.text.DateFormat; 3 | import java.text.SimpleDateFormat; 4 | import java.util.ArrayList; 5 | import java.util.Date; 6 | import java.util.LinkedHashMap; 7 | 8 | /** 9 | * Container of time related utilities. 10 | */ 11 | public class Timer { 12 | 13 | private static long birth = now(); 14 | private static LinkedHashMap points = new LinkedHashMap(); 15 | 16 | private static long secondInMillis = 1000; 17 | private static long minuteInMillis = secondInMillis * 60; 18 | 19 | /** 20 | * Resets the global starting point of the Timer. 21 | */ 22 | public static void resetClock() { 23 | birth = now(); 24 | } 25 | 26 | public static String getDateTime(){ 27 | DateFormat df = new SimpleDateFormat("H:mm:ss M/d/yy"); 28 | return df.format(new Date()); 29 | } 30 | 31 | /** 32 | * Kicks off a timer with the given name. 33 | */ 34 | public static void start(String name) { 35 | points.put(name, now()); 36 | } 37 | 38 | /** 39 | * Returns the elapsed time of the timer with the given name. 40 | * The format is [XX minutes, YYseconds]. 41 | */ 42 | public static String elapsed(String name) { 43 | if(!points.containsKey(name)) { 44 | return "[UNKNOWN TIMER]"; 45 | }else { 46 | long diff = now() - points.get(name); 47 | return readTime(diff); 48 | } 49 | } 50 | 51 | /** 52 | * Returns the number of elapsed seconds of a given timer; 53 | * -1 if the timer is unknown. 54 | * @param name the name of the timer 55 | */ 56 | public static double elapsedSeconds(String name) { 57 | if(!points.containsKey(name)) { 58 | return -1; 59 | }else { 60 | long diff = now() - points.get(name); 61 | return (diff / 1000); 62 | } 63 | } 64 | 65 | public static double elapsedMilliSeconds(String name) { 66 | if(!points.containsKey(name)) { 67 | return -1; 68 | }else { 69 | long diff = now() - points.get(name); 70 | return diff; 71 | } 72 | } 73 | 74 | /** 75 | * Returns the number of elapsed seconds since last clock reset. 76 | */ 77 | public static double elapsedSeconds() { 78 | long diff = now() - birth; 79 | return (diff / 1000.0); 80 | } 81 | 82 | public static int secondsToTimeOut() { 83 | return Config.timeout - (int) elapsedSeconds(); 84 | } 85 | 86 | public static boolean hasTimedOut() { 87 | return Config.timeout != 0 && elapsedSeconds() > Config.timeout; 88 | } 89 | 90 | public static int secondsToGroundingTimeOut() { 91 | return Config.groundingTimeout - (int) elapsedSeconds(); 92 | } 93 | 94 | /** 95 | * Prints the elapsed time since last clock reset. 96 | * The format is TIMER: [XX minutes, YYseconds]. 97 | */ 98 | public static void printElapsed() { 99 | UIMan.println("TIMER: " + elapsed()); 100 | } 101 | 102 | /** 103 | * Prints the elapsed time of the timer with the given name. 104 | * The format is TIMER name: [XX minutes, YYseconds]. 105 | */ 106 | public static void printElapsed(String name) { 107 | UIMan.println("TIMER " + name + ": " + elapsed(name)); 108 | } 109 | 110 | private static long now() { 111 | return System.currentTimeMillis(); 112 | } 113 | 114 | /** 115 | * Returns a string of elapsed time. 116 | */ 117 | public static String elapsed() { 118 | return readTime(now() - birth); 119 | } 120 | 121 | private static String readTime(long timeIntervalInMS) { 122 | long min = timeIntervalInMS / minuteInMillis; 123 | long sec = timeIntervalInMS / secondInMillis % 60; 124 | long mm = timeIntervalInMS % 1000; 125 | String t = String.format("[%d min, %d.%03d sec]", min, sec, mm); 126 | return t; 127 | } 128 | 129 | public static RunStat runStat = new RunStat(); 130 | 131 | public static class RunStat{ 132 | public double groundSec = 0; 133 | public double inferSec = 0; 134 | public double inferOps = 0; 135 | public long effectiveSteps = 0; 136 | 137 | public ArrayList turns = new ArrayList(); 138 | public ArrayList costs = new ArrayList(); 139 | 140 | public void addTurn(double cost){ 141 | turns.add(Timer.elapsedSeconds()); 142 | costs.add(cost); 143 | } 144 | 145 | public double getGroundTime(){ 146 | return groundSec; 147 | } 148 | 149 | public double getFlipRate(){ 150 | return inferOps / inferSec; 151 | } 152 | 153 | public void markGroundingDone(){ 154 | groundSec = Timer.elapsedSeconds(); 155 | } 156 | 157 | public void markInferDone(){ 158 | inferSec = Timer.elapsedSeconds() - groundSec; 159 | } 160 | 161 | public void setInferOps(long ops){ 162 | inferOps = ops; 163 | } 164 | 165 | public void report(){ 166 | System.out.println("============================"); 167 | boolean report_trace = false; 168 | if(report_trace){ 169 | System.out.println("Trace:"); 170 | for(int i=0; i logX) { 17 | double temp = logX; 18 | logX = logY; 19 | logY = temp; 20 | } 21 | 22 | if (logX == Double.NEGATIVE_INFINITY) { 23 | return logX; 24 | } 25 | 26 | double negDiff = logY - logX; 27 | if (negDiff < -200) { 28 | return logX; 29 | } 30 | 31 | return logX + java.lang.Math.log(1.0 + java.lang.Math.exp(negDiff)); 32 | } 33 | 34 | public void tallylog(double plus){ 35 | value = logAdd(value, plus); 36 | } 37 | 38 | public synchronized void tallyDouble(double plus){ 39 | value = value + plus; 40 | } 41 | 42 | public String toString(){ 43 | return "" + value; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/myInt.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | public class myInt{ 4 | public int value = -1; 5 | 6 | public void addOne(){ 7 | value ++; 8 | } 9 | 10 | public void subOne(){ 11 | value --; 12 | } 13 | 14 | public myInt(int _value){ 15 | value = _value; 16 | } 17 | 18 | public String toString(){ 19 | return "" + value; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/main/java/tuffy/util/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | package 4 | 5 | 6 | Miscellaneous utilities. 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/main/java/tuffy/util/runAllTestCases.java: -------------------------------------------------------------------------------- 1 | package tuffy.util; 2 | 3 | import org.junit.internal.TextListener; 4 | import org.junit.runner.JUnitCore; 5 | 6 | import tuffy.test.*; 7 | 8 | public class runAllTestCases { 9 | 10 | /** 11 | * @param args 12 | */ 13 | public static void main(String[] args) { 14 | 15 | JUnitCore junit = new JUnitCore(); 16 | junit.addListener(new TextListener(System.out)); 17 | junit.run( 18 | // LearnerTest.class, 19 | AtomTest.class, 20 | ClauseTest.class, 21 | ConfigTest.class, 22 | GAtomTest.class, 23 | GClauseTest.class, 24 | GroundingTest.class, 25 | InferenceTest.class, 26 | LiteralTest.class, 27 | ParsingLoadingTest.class, 28 | PredicateTest.class, 29 | TermTest.class, 30 | TupleTest.class, 31 | TypeTest.class 32 | ); 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/tuffy/worker/ds/MLEWorld.java: -------------------------------------------------------------------------------- 1 | package tuffy.worker.ds; 2 | 3 | import java.util.BitSet; 4 | 5 | 6 | 7 | public class MLEWorld{ 8 | 9 | public BitSet bitmap; 10 | public double freq = 0; 11 | public double weight = 0; 12 | public double logCost = Double.NEGATIVE_INFINITY; 13 | 14 | public MLEWorld(BitSet _world){ 15 | bitmap = _world; 16 | } 17 | 18 | public void tallyFreq(){ 19 | freq ++; 20 | } 21 | 22 | public void tallyFreq(double _freq){ 23 | freq += _freq; 24 | } 25 | 26 | public void tallyWeight(double _weight){ 27 | weight += _weight; 28 | } 29 | 30 | public void tallyLogCost(double _logY){ 31 | logCost = logAdd(logCost, _logY); 32 | } 33 | 34 | public double logAdd(double logX, double logY) { 35 | 36 | if (logY > logX) { 37 | double temp = logX; 38 | logX = logY; 39 | logY = temp; 40 | } 41 | 42 | if (logX == Double.NEGATIVE_INFINITY) { 43 | return logX; 44 | } 45 | 46 | double negDiff = logY - logX; 47 | if (negDiff < -200) { 48 | return logX; 49 | } 50 | 51 | return logX + java.lang.Math.log(1.0 + java.lang.Math.exp(negDiff)); 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /version.sbt: -------------------------------------------------------------------------------- 1 | version in ThisBuild := "0.5.1-SNAPSHOT" --------------------------------------------------------------------------------