OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
AssignLink.cc
Go to the documentation of this file.
1 /*
2  * AssignLink.cc
3  *
4  * Copyright (C) 2015 Linas Vepstas
5  *
6  * Author: Linas Vepstas <linasvepstas@gmail.com> January 2009
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
11  * exceptions
12  * at http://opencog.org/wiki/Licenses
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public
20  * License
21  * along with this program; if not, write to:
22  * Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
30 
31 #include "AssignLink.h"
32 
33 using namespace opencog;
34 
37  : FunctionLink(ASSIGN_LINK, oset, tv, av)
38 {
39  init(oset);
40 }
41 
44  : FunctionLink(t, oset, tv, av)
45 {
46  if (not classserver().isA(t, ASSIGN_LINK))
47  {
48  const std::string& tname = classserver().getTypeName(t);
49  throw InvalidParamException(TRACE_INFO,
50  "Expecting an AssignLink, got %s", tname.c_str());
51  }
52 
53  init(oset);
54 }
55 
57  : FunctionLink(l)
58 {
59  // Type must be as expected
60  Type tscope = l.getType();
61  if (not classserver().isA(tscope, ASSIGN_LINK))
62  {
63  const std::string& tname = classserver().getTypeName(tscope);
64  throw InvalidParamException(TRACE_INFO,
65  "Expecting an AssignLink, got %s", tname.c_str());
66  }
67 
68  init(l.getOutgoingSet());
69 }
70 
71 // ---------------------------------------------------------------
72 
73 void AssignLink::init(const HandleSeq& oset)
74 {
75  // The first member of the handleset must be a TypeNode, and it must
76  // name a valid atom type.
77 
78  if (0 == oset.size())
79  throw InvalidParamException(TRACE_INFO,
80  "AssignLinks must have members!");
81 
82  Type t = oset[0]->getType();
83  if (TYPE_NODE != t)
84  throw InvalidParamException(TRACE_INFO,
85  "Invalid format for a AssignLink! First member must be a type node!");
86 
87  const std::string& name = NodeCast(oset[0])->getName();
88  if (not classserver().isDefined(name))
89  throw InvalidParamException(TRACE_INFO,
90  "Invalid format for a AssignLink! Not a defined type!");
91 
92  // Cache the type and the oset
93  _link_type = classserver().getType(name);
94 
95  for (size_t j=1; j < oset.size(); j++)
96  _outset.push_back(oset[j]);
97 
98  _osetz = _outset.size();
99 }
100 
101 // ---------------------------------------------------------------
102 
104 {
105  // XXX This is probably wrong ... if the as is null, we should
106  // probably use the atomspace that this link is in, right?
107  // We need to make a decision here and in many other places...
108  if (NULL == as)
110 
111  // First, remove everything resembling this pattern.
112  IncomingSet iset = _outset[0]->getIncomingSet();
113  for (const LinkPtr& lp : iset)
114  {
115  // Wrong type, can't delete that!
116  if (_link_type != lp->getType()) continue;
117  // Wrong Arity, can't delete that either!
118  if (_osetz != lp->getArity()) continue;
119 
120  const HandleSeq& hs = lp->getOutgoingSet();
121  if (hs[0] != _outset[0]) continue;
122 
123  bool match = true;
124  for (size_t i=1; i < _osetz; i++)
125  {
126  // Contains a variable, or doesn't match -- don't delete.
127  if (VARIABLE_NODE == hs[i]->getType())
128  {
129  match = false;
130  break;
131  }
132  }
133  if (not match) continue;
134 
135  // Hit it with a hammer. We have to set the recursive flag
136  // to true, to break out of any links that might contain us.
137  // This is pretty nasty behavior, and condemns assignable
138  // atoms to always live at the very top of the atomspace.
139  // However, I don't see any plausable alternatives to this,
140  // right now.
141  as->remove_atom(Handle(lp), true);
142  }
143 
144  return as->add_atom(createLink(_link_type, _outset));
145 }
146 
147 // ============================================================
148 
150 {
151  if (NULL == as)
153  return as->add_atom(createLink(_link_type, _outset));
154 }
155 
158  : AssignLink(INSERT_LINK, oset, tv, av)
159 {}
160 
162  : AssignLink(l)
163 {
164  // Type must be as expected
165  Type tscope = l.getType();
166  if (not classserver().isA(tscope, INSERT_LINK))
167  {
168  const std::string& tname = classserver().getTypeName(tscope);
169  throw InvalidParamException(TRACE_INFO,
170  "Expecting a InsertLink, got %s", tname.c_str());
171  }
172 }
173 
174 // ============================================================
175 
185 {
186  // Are there *any* constants in the outgoing set?
187  // narrowst will be -1 if they're all free variables.
188  // narrowest helps make the next loop small...
189  int narrowest = -1;
190  size_t narsz = SIZE_MAX;
191  for (size_t i=0; i < _osetz; i++)
192  {
193  if (VARIABLE_NODE == _outset[i]->getType()) continue;
194  size_t isz = _outset[i]->getIncomingSetSize();
195  if (isz < narsz)
196  {
197  narsz = isz;
198  narrowest = i;
199  }
200  }
201 
202  // Delete matching constant (closed) links
203  if (0 <= narrowest)
204  {
205  IncomingSet iset = _outset[narrowest]->getIncomingSet();
206  for (const LinkPtr& lp : iset)
207  {
208  // Wrong type, can't delete that!
209  if (_link_type != lp->getType()) continue;
210  // Wrong Arity, can't delete that either!
211  if (_osetz != lp->getArity()) continue;
212 
213  const HandleSeq& hs = lp->getOutgoingSet();
214  bool match = true;
215  for (size_t i=0; i < _osetz; i++)
216  {
217  if (VARIABLE_NODE == _outset[i]->getType()) continue;
218 
219  // Contains a variable, or doesn't match -- don't delete.
220  if (VARIABLE_NODE == hs[i]->getType() or
221  _outset[i] != hs[i])
222  {
223  match = false;
224  break;
225  }
226  }
227  if (not match) continue;
228 
229  as->remove_atom(Handle(lp), true);
230  }
231  return Handle::UNDEFINED;
232  }
233 
234  // If we are here, then the entire outset consisted of free variables.
235  // In this case, deleted everything that has the same arity, and does
236  // not contain variables.
237  HandleSeq seq;
239  for (const Handle& h : seq)
240  {
241  LinkPtr lp = LinkCast(h);
242 
243  // Wrong Arity, cannot delete that.
244  if (_osetz != lp->getArity()) continue;
245 
246  const HandleSeq& hs = lp->getOutgoingSet();
247  bool match = true;
248  for (size_t i=0; i < _osetz; i++)
249  {
250  // Contains a variable -- don't delete.
251  if (VARIABLE_NODE == hs[i]->getType())
252  {
253  match = false;
254  break;
255  }
256  }
257 
258  if (not match) continue;
259  as->remove_atom(h, true);
260  }
261  return Handle::UNDEFINED;
262 }
263 
266  : AssignLink(REMOVE_LINK, oset, tv, av)
267 {}
268 
270  : AssignLink(l)
271 {
272  // Type must be as expected
273  Type tscope = l.getType();
274  if (not classserver().isA(tscope, REMOVE_LINK))
275  {
276  const std::string& tname = classserver().getTypeName(tscope);
277  throw InvalidParamException(TRACE_INFO,
278  "Expecting a RemoveLink, got %s", tname.c_str());
279  }
280 }
281 
282 /* ===================== END OF FILE ===================== */
#define createLink
Definition: Link.h:269
friend class Handle
Definition: Atom.h:79
std::vector< Handle > HandleSeq
a list of handles
Definition: Handle.h:246
std::shared_ptr< TruthValue > TruthValuePtr
Definition: TruthValue.h:85
std::shared_ptr< AttentionValue > AttentionValuePtr
Type getType() const
Definition: Atom.h:197
std::shared_ptr< Link > LinkPtr
Definition: Atom.h:53
void get_handles_by_type(HandleSeq &appendToHandles, Type type, bool subclass=false) const
Definition: AtomSpace.h:392
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
Definition: ClassServer.cc:159
static NodePtr NodeCast(const Handle &h)
Definition: Node.h:113
static const Handle UNDEFINED
Definition: Handle.h:77
bool remove_atom(Handle h, bool recursive=false)
Definition: AtomSpace.cc:344
const std::string & getTypeName(Type type)
Definition: ClassServer.cc:148
static LinkPtr LinkCast(const Handle &h)
Definition: Link.h:263
std::vector< LinkPtr > IncomingSet
Definition: Atom.h:55
Type getType(const std::string &typeName)
Definition: ClassServer.cc:138
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40
Handle add_atom(AtomPtr atom, bool async=false)
Definition: AtomSpace.cc:100