public void AtomSlots() { Atom atom = new Atom("spending", new Slot("client", new Variable("buyer")), new Function(Function.FunctionResolutionType.Binder, "min(5000,EUR)", null, "min", new string[] { "5000", "EUR" })); Assert.AreEqual(typeof(Variable), atom.GetPredicate("client").GetType(), "Slot predicate"); Atom clone = (Atom)atom.Clone(); atom = null; Assert.AreEqual(typeof(Variable), clone.GetPredicate("client").GetType(), "Slot predicate after cloning"); }
/* Atom Utils */ /// <summary> /// Resolves all Function predicates by replacing them by their String representations. /// </summary> /// <param name="atom">The Atom to resolve.</param> /// <returns>A new Atom where all Function predicates have been resolved. If no /// Function predicate exists, it returns a clone of the current Atom.</returns> internal static Atom ResolveFunctions(Atom atom) { if (atom.HasFunction) { var predicates = new IPredicate[atom.Members.Length]; for (var i = 0; i < atom.Members.Length; i++) { if (atom.Members[i] is Function) { predicates[i] = new Individual(atom.Members[i].ToString()); } else { predicates[i] = atom.Members[i]; } } return(new Atom(atom.Negative, atom.Type, predicates)); } return((Atom)atom.Clone()); }
public ArrayAtom GetTextOperator() { Debug.Assert(_text != null); // get data and widths byte[] section = new byte[_text.StreamLength]; Array.Copy(_data, _text.StreamOffset, section, 0, _text.StreamLength); IDictionary <char, int> widths = _text.Font.Widths; // convert to atoms ArrayAtom textOp = ArrayAtom.FromContentStream(section); string srcOp = ((OpAtom)textOp[1]).Text; int numParams = srcOp == "\"" ? 4 : 2; Debug.Assert(textOp.Count == numParams); ArrayAtom srcParams = textOp[numParams == 4 ? 2 : 0] as ArrayAtom; if (srcParams == null) { Debug.Assert(srcOp != "TJ"); srcParams = new ArrayAtom(); srcParams.Add(textOp[0]); } ArrayAtom dstParams = new ArrayAtom(); // copy items int textSpanIndex = 0; for (int i = 0; i < srcParams.Count; i++) { Atom item = srcParams[i]; if (item is StringAtom) { StringAtom str = (StringAtom)item; Tuple <string, bool[]> redaction = null; _redactions.TryGetValue(textSpanIndex++, out redaction); if (redaction == null) { dstParams.Add(item.Clone()); } else { string encoded = str.Text; string whole = redaction.Item1; bool[] redacted = redaction.Item2; Debug.Assert((encoded.Length == whole.Length) || (encoded.Length == whole.Length * 2)); int bytesPerChar = encoded.Length / whole.Length; int p1 = 0; while (p1 < redacted.Length) { bool hidden = redacted[p1]; int width1000ths = 0; int p2; for (p2 = p1; p2 < redacted.Length; p2++) { if (hidden != redacted[p2]) { break; } if (hidden) { width1000ths += widths[whole[p2]]; } } if (hidden) { dstParams.Add(new NumAtom(-width1000ths)); } else { string sub1 = encoded.Substring(p1 * bytesPerChar, (p2 - p1) * bytesPerChar); if (sub1.Length > 0) { dstParams.Add(new StringAtom(sub1)); } } p1 = p2; } } } else if (item is NumAtom) { NumAtom num = (NumAtom)item; dstParams.Add(item.Clone()); } else { Debug.Assert(false); } } // make new operators ArrayAtom newTextOp = new ArrayAtom(); if (srcOp == "\'") { newTextOp.Add(new OpAtom("T*")); } else if (srcOp == "\"") { newTextOp.Add(textOp[0].Clone()); newTextOp.Add(new OpAtom("Tw")); newTextOp.Add(textOp[1].Clone()); newTextOp.Add(new OpAtom("Tc")); newTextOp.Add(new OpAtom("T*")); } newTextOp.Add(dstParams); newTextOp.Add(new OpAtom("TJ")); return(newTextOp); }