1 | package felix.dstruct; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.HashMap; |
5 | import java.util.HashSet; |
6 | |
7 | import felix.dstruct.StatOperator.OPType; |
8 | |
9 | |
10 | import tuffy.db.RDB; |
11 | import tuffy.infer.ds.GClause; |
12 | import tuffy.mln.Clause; |
13 | import tuffy.mln.Literal; |
14 | import tuffy.mln.Predicate; |
15 | import tuffy.mln.Term; |
16 | import tuffy.mln.Type; |
17 | import tuffy.mln.Clause.ClauseInstance; |
18 | import tuffy.ra.ConjunctiveQuery; |
19 | import tuffy.ra.Expression; |
20 | import tuffy.util.Config; |
21 | import tuffy.util.ExceptionMan; |
22 | |
23 | |
24 | /** |
25 | * The clause object used in Felix, which extends |
26 | * the Clause class in Tuffy to contain Felix-related |
27 | * fields and methods. |
28 | * |
29 | * @author Ce Zhang |
30 | * |
31 | */ |
32 | public class FelixClause extends Clause{ |
33 | |
34 | |
35 | @SuppressWarnings("unchecked") |
36 | public FelixClause clone(){ |
37 | FelixClause ret = new FelixClause(); |
38 | |
39 | ret.bilits = (ArrayList<Literal>) this.bilits.clone(); |
40 | |
41 | ret.constraints = new ArrayList<Expression>(); |
42 | for(Expression sub : this.constraints){ |
43 | ret.constraints.add(sub.clone()); |
44 | } |
45 | |
46 | ret.cost = this.cost; |
47 | ret.existentialVars = (ArrayList<String>) this.existentialVars.clone(); |
48 | ret.exprWeight = this.exprWeight; |
49 | ret.id = this.id; |
50 | ret.instances = (ArrayList<ClauseInstance>) this.instances.clone(); |
51 | ret.isTemplate = this.isTemplate; |
52 | ret.lits = (ArrayList<Literal>) this.lits.clone(); |
53 | ret.metaTypes = (ArrayList<Type>) this.metaTypes.clone(); |
54 | ret.metaVars = (ArrayList<String>) this.metaVars.clone(); |
55 | ret.name = this.name; |
56 | ret.predIndex = (HashMap<Predicate, ArrayList<Literal>>) this.predIndex.clone(); |
57 | ret.reglits = (ArrayList<Literal>) this.reglits.clone(); |
58 | ret.relIntanceClauses = this.relIntanceClauses; |
59 | ret.signature = this.signature; |
60 | ret.specText = (ArrayList<String>) this.specText.clone(); |
61 | ret.sqlFromList = this.sqlFromList; |
62 | ret.sqlPivotAttrsList = this.sqlPivotAttrsList; |
63 | ret.sqlWhereBindings = this.sqlWhereBindings; |
64 | ret.uNames = (ArrayList<String>) this.uNames.clone(); |
65 | ret.varWeight = this.varWeight; |
66 | ret.violatedGClauses = (ArrayList<GClause>) this.violatedGClauses.clone(); |
67 | ret.weight = this.weight; |
68 | |
69 | |
70 | return ret; |
71 | } |
72 | |
73 | /** |
74 | * @deprecated |
75 | */ |
76 | public boolean isBinaryLRRules = false; |
77 | |
78 | |
79 | /** |
80 | * See {@link StatOperator#translateFelixClasesIntoFactorGraphEdgeQueries(FelixPredicate, boolean, dstruct.FelixPredicate.FPProperty...)} |
81 | * @param sop |
82 | * @param toBeHead |
83 | * @param forceRecursive |
84 | * @return |
85 | */ |
86 | public ConjunctiveQuery toSimplifiedFactorGraphQuery(StatOperator sop, FelixPredicate toBeHead, boolean forceRecursive){ |
87 | |
88 | try{ |
89 | |
90 | ConjunctiveQuery cq = new ConjunctiveQuery(); |
91 | |
92 | //pick head literals |
93 | int nOfTargetLiteral = 0; |
94 | ArrayList<Term> headTerms = new ArrayList<Term>(); |
95 | ArrayList<Type> headTypes = new ArrayList<Type>(); |
96 | ArrayList<Literal> headLiterals = new ArrayList<Literal>(); |
97 | for(Literal l : this.getRegLiterals()){ |
98 | if(nOfTargetLiteral == 1 && forceRecursive == true){ |
99 | break; |
100 | } |
101 | |
102 | if(l.getPred().getName().equals(toBeHead.getName())){ |
103 | nOfTargetLiteral ++; |
104 | headTerms.addAll(l.getTerms()); |
105 | headLiterals.add(l); |
106 | for(int i=0;i<l.getPred().arity();i++){ |
107 | headTypes.add(l.getPred().getTypeAt(i)); |
108 | } |
109 | } |
110 | } |
111 | |
112 | // currently, we do not consider hyper-graph edges |
113 | if(nOfTargetLiteral > 2 && forceRecursive == false){ |
114 | ExceptionMan.die("Too many matched literals for predicate " + toBeHead); |
115 | } |
116 | |
117 | FelixPredicate tmpHeadPredicate = new FelixPredicate(FelixPredicate.getNextTmpPredicateName(), false); |
118 | for(Type type : headTypes){ |
119 | tmpHeadPredicate.appendArgument(type); |
120 | } |
121 | RDB db = RDB.getRDBbyConfig(Config.db_schema); |
122 | tmpHeadPredicate.prepareDB(db); |
123 | db.close(); |
124 | |
125 | Literal lhead = new Literal(tmpHeadPredicate, true); |
126 | for(Term t : headTerms){ |
127 | lhead.appendTerm(t); |
128 | } |
129 | cq.setHead(lhead); |
130 | cq.sourceClause = this; |
131 | |
132 | int ctOpen = 0; |
133 | boolean lastSense = false; |
134 | Literal lastLiteral = null; |
135 | for(Literal l : this.getRegLiterals()){ |
136 | if(headLiterals.contains(l)){ |
137 | continue; |
138 | } |
139 | ctOpen ++; |
140 | Literal negL = (Literal) l.clone(); |
141 | negL.setSense(!negL.getSense()); |
142 | lastLiteral = negL; |
143 | lastSense = negL.getSense(); |
144 | cq.addBodyLit(negL); |
145 | } |
146 | |
147 | boolean flipFlag = false; |
148 | if(ctOpen == 1 && lastSense == false){ |
149 | flipFlag = true; |
150 | lastLiteral.setSense(!lastLiteral.getSense()); |
151 | } |
152 | |
153 | cq.setWeight(0); |
154 | |
155 | // set weight for the factor graph's edges |
156 | if(headLiterals.size() == 1){ |
157 | if(headLiterals.get(0).getSense() == true){ |
158 | if(this.hasEmbeddedWeight()){ |
159 | cq.inverseEmbededWeight = (flipFlag == false? false : true); |
160 | }else{ |
161 | cq.setWeight(flipFlag == false? this.getWeight(): -this.getWeight()); |
162 | } |
163 | }else{ |
164 | if(this.hasEmbeddedWeight()){ |
165 | cq.inverseEmbededWeight = (flipFlag == false? true : false); |
166 | }else{ |
167 | cq.setWeight((flipFlag == false?-this.getWeight():this.getWeight())); |
168 | } |
169 | } |
170 | }else{ |
171 | if(headLiterals.get(0).getSense() != headLiterals.get(1).getSense()){ |
172 | if(this.hasEmbeddedWeight()){ |
173 | cq.inverseEmbededWeight = (flipFlag == false? false : true); |
174 | }else{ |
175 | cq.setWeight(flipFlag == false? this.getWeight(): -this.getWeight()); |
176 | } |
177 | }else{ |
178 | if(this.hasEmbeddedWeight()){ |
179 | cq.inverseEmbededWeight = (flipFlag == false? true : false); |
180 | }else{ |
181 | cq.setWeight((flipFlag == false?-this.getWeight():this.getWeight())); |
182 | } |
183 | } |
184 | } |
185 | |
186 | if(sop.clauseConstraints.get(this) != null){ |
187 | cq.addConstraintAll(sop.clauseConstraints.get(this)); |
188 | } |
189 | cq.addConstraintAll(this.getConstraints()); |
190 | |
191 | return cq; |
192 | |
193 | }catch(Exception e){ |
194 | e.printStackTrace(); |
195 | return null; |
196 | } |
197 | |
198 | } |
199 | |
200 | } |
201 | |