OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Link.cc
Go to the documentation of this file.
1 /*
2  * opencog/atomspace/Link.cc
3  *
4  * Copyright (C) 2008-2010 OpenCog Foundation
5  * Copyright (C) 2002-2007 Novamente LLC
6  * All Rights Reserved
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Affero General Public License v3 as
10  * published by the Free Software Foundation and including the exceptions
11  * at http://opencog.org/wiki/Licenses
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Affero General Public License
19  * along with this program; if not, write to:
20  * Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #include <stdio.h>
25 
28 #include <opencog/atomspace/Node.h>
29 #include <opencog/util/exceptions.h>
30 #include <opencog/util/Logger.h>
31 
32 #include "Link.h"
33 
34 //#define DPRINTF printf
35 #define DPRINTF(...)
36 
37 using namespace opencog;
38 
40 {
41  bool operator()(const Handle& h1, const Handle& h2) const {
42  return (Handle::compare(h1, h2) < 0);
43  }
44 };
45 
46 void Link::resort(void)
47 {
48  std::sort(_outgoing.begin(), _outgoing.end(), HandleComparison());
49 }
50 
51 void Link::init(const std::vector<Handle>& outgoingVector)
52  throw (InvalidParamException)
53 {
54  if (not classserver().isA(_type, LINK)) {
55  throw InvalidParamException(TRACE_INFO,
56  "Link ctor: Atom type is not a Link: '%d' %s.",
57  _type, classserver().getTypeName(_type).c_str());
58  }
59 
60  _outgoing = outgoingVector;
61  // If the link is unordered, it will be normalized by sorting the
62  // elements in the outgoing list.
63  if (classserver().isA(_type, UNORDERED_LINK)) {
64  resort();
65  }
66 }
67 
69 {
70  DPRINTF("Deleting link:\n%s\n", this->toString().c_str());
71 }
72 
73 std::string Link::toShortString(std::string indent)
74 {
75  std::stringstream answer;
76  std::string more_indent = indent + " ";
77 
78  answer << indent << "(" << classserver().getTypeName(_type);
79  answer << " " << getTruthValue()->toString() << "\n";
80 
81  // Here the target string is made. If a target is a node, its name is
82  // concatenated. If it's a link, all its properties are concatenated.
83  for (const Handle& h : _outgoing) {
84  if (h.operator->() != NULL)
85  answer << h->toShortString(more_indent);
86  else
87  answer << indent << "Undefined Atom!\n";
88  }
89 
90  answer << indent << ") ; [" << _uuid << "]\n";
91  return answer.str();
92 }
93 
94 std::string Link::toString(std::string indent)
95 {
96  std::string answer;
97  std::string more_indent = indent + " ";
98 #define BUFSZ 1024
99  static char buf[BUFSZ];
100 
101  snprintf(buf, BUFSZ, "(%s (av %d %d %d) %s\n",
102  classserver().getTypeName(_type).c_str(),
103  (int)getAttentionValue()->getSTI(),
104  (int)getAttentionValue()->getLTI(),
105  (int)getAttentionValue()->getVLTI(),
106  getTruthValue()->toString().c_str());
107  answer = indent + buf;
108  // Here the targets string is made. If a target is a node, its name is
109  // concatenated. If it's a link, all its properties are concatenated.
110  for (const Handle& h : _outgoing) {
111  if (h.operator->() != NULL)
112  answer += h->toString(more_indent);
113  else
114  answer += indent + "Undefined Atom!\n";
115  }
116 
117  answer += indent + ") ; [" +
118  std::to_string(_uuid).c_str() + "]\n";
119  return answer;
120 }
121 
122 bool Link::isSource(Handle handle) const throw (InvalidParamException)
123 {
124  // On ordered links, only the first position in the outgoing set is a source
125  // of this link. So, if the handle given is equal to the first position,
126  // true is returned.
127  Arity arity = getArity();
128  if (classserver().isA(_type, ORDERED_LINK)) {
129  return arity > 0 && _outgoing[0] == handle;
130  } else if (classserver().isA(_type, UNORDERED_LINK)) {
131  // If the link is unordered, the outgoing set is scanned, and the
132  // method returns true if any position is equal to the handle given.
133  for (Arity i = 0; i < arity; i++) {
134  if (_outgoing[i] == handle) {
135  return true;
136  }
137  }
138  return false;
139  } else {
140  throw InvalidParamException(TRACE_INFO, "Link::isSource(Handle) unknown link type %d", _type);
141  }
142  return false;
143 }
144 
145 bool Link::isSource(size_t i) const throw (IndexErrorException, InvalidParamException)
146 {
147  // tests if the int given is valid.
148  if (i > getArity()) {
149  throw IndexErrorException(TRACE_INFO, "Link::isSource(size_t) invalid index argument");
150  }
151 
152  // on ordered links, only the first position in the outgoing set is a source
153  // of this link. So, if the int passed is 0, true is returned.
154  if (classserver().isA(_type, ORDERED_LINK)) {
155  return i == 0;
156  } else if (classserver().isA(_type, UNORDERED_LINK)) {
157  // on unordered links, the only thing that matters is if the int passed
158  // is valid (if it is within 0..arity).
159  return true;
160  } else {
161  throw InvalidParamException(TRACE_INFO, "Link::isSource(int) unknown link type %d", _type);
162  }
163 }
164 
165 bool Link::isTarget(Handle handle) const throw (InvalidParamException)
166 {
167  // On ordered links, the first position of the outgoing set defines the
168  // source of the link. The other positions are targets. So, it scans the
169  // outgoing set from the second position searching for the given handle. If
170  // it is found, true is returned.
171  Arity arity = getArity();
172  if (classserver().isA(_type, ORDERED_LINK)) {
173  for (Arity i = 1; i < arity; i++) {
174  if (_outgoing[i] == handle) {
175  return true;
176  }
177  }
178  return false;
179  } else if (classserver().isA(_type, UNORDERED_LINK)) {
180  // If the links is unordered, all the outgoing set is scanned.
181  for (Arity i = 0; i < arity; i++) {
182  if (_outgoing[i] == handle) {
183  return true;
184  }
185  }
186  return false;
187  } else {
188  throw InvalidParamException(TRACE_INFO, "Link::isTarget(Handle) unknown link type %d", _type);
189  }
190  return false;
191 }
192 
193 bool Link::isTarget(size_t i) const throw (IndexErrorException, InvalidParamException)
194 {
195  // tests if the int given is valid.
196  if (i > getArity()) {
197  throw IndexErrorException(TRACE_INFO, "Link::istarget(int) invalid index argument");
198  }
199 
200  // on ordered links, the first position of the outgoing set defines the
201  // source of the link. The other positions are targets.
202  if (classserver().isA(_type, ORDERED_LINK)) {
203  return i != 0;
204  } else if (classserver().isA(_type, UNORDERED_LINK)) {
205  // on unorderd links, the only thing that matter is if the position is
206  // valid.
207  return true;
208  } else {
209  throw InvalidParamException(TRACE_INFO, "Link::isTarget(int) unkown link type");
210  }
211  return false;
212 }
213 
214 bool Link::operator==(const Atom& other) const
215 {
216  if (getType() != other.getType()) return false;
217  const Link& olink = dynamic_cast<const Link&>(other);
218 
219  Arity arity = getArity();
220  if (arity != olink.getArity()) return false;
221  for (Arity i = 0; i < arity; i++)
222  if (_outgoing[i] != olink._outgoing[i]) return false;
223  return true;
224 }
225 
226 bool Link::operator!=(const Atom& other) const
227 {
228  return !(*this == other);
229 }
230 
AttentionValuePtr getAttentionValue()
Definition: Atom.cc:146
UUID _uuid
Definition: Atom.h:93
Type getType() const
Definition: Atom.h:197
AttentionValue::lti_t getLTI()
Definition: Atom.h:231
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
Definition: ClassServer.cc:159
AttentionValue::vlti_t getVLTI()
Definition: Atom.h:236
bool operator()(const Handle &h1, const Handle &h2) const
Definition: Link.cc:41
const std::string & getTypeName(Type type)
Definition: ClassServer.cc:148
TruthValuePtr getTruthValue()
Definition: Atom.cc:104
AttentionValue::sti_t getSTI()
Handy-dandy convenience getters for attention values.
Definition: Atom.h:226
Type _type
Definition: Atom.h:96
unsigned short Arity
arity of Links, represented as short integer (16 bits)
Definition: Link.h:40
static int compare(const Handle &h1, const Handle &h2)
Definition: Handle.h:168