OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PutLink.cc
Go to the documentation of this file.
1 /*
2  * opencog/atoms/core/PutLink.cc
3  *
4  * Copyright (C) 2015 Linas Vepstas
5  * All Rights Reserved
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License v3 as
9  * published by the Put Software Foundation and including the exceptions
10  * at http://opencog.org/wiki/Licenses
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program; if not, write to:
19  * Put Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #include <opencog/atomspace/atom_types.h>
25 #include "PutLink.h"
26 
27 using namespace opencog;
28 
32  : FreeLink(PUT_LINK, oset, tv, av)
33 {
34  init();
35 }
36 
40  : FreeLink(PUT_LINK, a, tv, av)
41 {
42  init();
43 }
44 
48  : FreeLink(t, oset, tv, av)
49 {
50  if (not classserver().isA(t, PUT_LINK))
51  throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
52  init();
53 }
54 
58  : FreeLink(t, a, tv, av)
59 {
60  if (not classserver().isA(t, PUT_LINK))
61  throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
62  init();
63 }
64 
65 PutLink::PutLink(Type t, const Handle& a, const Handle& b,
68  : FreeLink(t, a, b, tv, av)
69 {
70  if (not classserver().isA(t, PUT_LINK))
71  throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
72  init();
73 }
74 
76  : FreeLink(l)
77 {
78  Type tscope = l.getType();
79  if (not classserver().isA(tscope, PUT_LINK))
80  throw InvalidParamException(TRACE_INFO, "Expecting a PutLink");
81  init();
82 }
83 
84 /* ================================================================= */
85 
115 void PutLink::init(void)
116 {
117  if (2 != _outgoing.size())
118  throw InvalidParamException(TRACE_INFO, "PutLinks should be arity 2!");
119 
120  const Handle& body = _outgoing[0];
121  if (VARIABLE_NODE == body->getType())
122  {
123  _varseq.push_back(body);
124  }
125  else
126  {
127  LinkPtr lll(LinkCast(body));
128  if (lll)
129  {
130  std::set<Handle> varset;
131  find_vars(varset, lll->getOutgoingSet());
132  }
133  }
134  build_index();
135 
136  // OK, now for the values.
137  if (_varseq.size() == 1) return;
138 
139  LinkPtr lval(LinkCast(_outgoing[1]));
140  if (lval->getType() == LIST_LINK)
141  {
142  if (lval->getArity() != _varseq.size())
143  throw InvalidParamException(TRACE_INFO,
144  "PutLink has mismatched size! Expected %zu, got %zu\n",
145  _varseq.size(), lval->getArity());
146  return;
147  }
148  if (lval->getType() != SET_LINK)
149  throw InvalidParamException(TRACE_INFO,
150  "PutLink was expecting a ListLink or SetLink!");
151 
152  for (const Handle& h : lval->getOutgoingSet())
153  {
154  LinkPtr lse(LinkCast(h));
155  if (lse->getType() != LIST_LINK)
156  throw InvalidParamException(TRACE_INFO,
157  "PutLink was expecting a ListLink here");
158  if (lse->getArity() != _varseq.size())
159  throw InvalidParamException(TRACE_INFO,
160  "PutLink set element has mismatched size! Expected %zu, got %zu\n",
161  _varseq.size(), lse->getArity());
162  }
163 }
164 /* ================================================================= */
165 
199  const HandleSeq& args) const
200 {
201  // If it is a singleton, just return that singleton.
202  std::map<Handle, unsigned int>::const_iterator idx;
203  idx = _index.find(term);
204  if (idx != _index.end())
205  return args.at(idx->second);
206 
207  // If its a node, and its not a variable, then it is a constant,
208  // and just return that.
209  LinkPtr lterm(LinkCast(term));
210  if (NULL == lterm) return term;
211 
212  // QuoteLinks halt the reursion
213  if (QUOTE_LINK == term->getType()) return term;
214 
215  // Recursively fill out the subtrees.
216  HandleSeq oset;
217  for (const Handle& h : lterm->getOutgoingSet())
218  {
219  oset.push_back(substitute_nocheck(h, args));
220  }
221  return Handle(createLink(term->getType(), oset));
222 }
223 
225 {
226  const Handle& body = _outgoing[0];
227  const Handle& vals = _outgoing[1];
228 
229  if (1 == _varseq.size())
230  {
231  HandleSeq oset;
232  oset.push_back(vals);
233  return substitute_nocheck(body, oset);
234  }
235  if (vals->getType() == LIST_LINK)
236  {
237  const HandleSeq& oset = LinkCast(vals)->getOutgoingSet();
238  return substitute_nocheck(body, oset);
239  }
240 
241  OC_ASSERT(vals->getType() == SET_LINK,
242  "Should have checked for this earlier, tin the ctor");
243 
244  HandleSeq bset;
245  for (Handle h : LinkCast(vals)->getOutgoingSet())
246  {
247  const HandleSeq& oset = LinkCast(h)->getOutgoingSet();
248  bset.push_back(substitute_nocheck(body, oset));
249  }
250  return Handle(createLink(SET_LINK, bset));
251 }
252 
254 {
255  return do_reduce();
256 }
257 
258 /* ===================== 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
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
Definition: ClassServer.cc:159
tuple args
Definition: benchmark.py:79
static LinkPtr LinkCast(const Handle &h)
Definition: Link.h:263
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40