OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ArithmeticLink.cc
Go to the documentation of this file.
1 /*
2  * opencog/atoms/reduct/ArithmeticLink.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 Arithmetic 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  * Arithmetic Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #include <limits>
24 
25 #include <opencog/atomspace/atom_types.h>
29 #include "ArithmeticLink.h"
30 
31 using namespace opencog;
32 
36  : FoldLink(ARITHMETIC_LINK, oset, tv, av)
37 {
38  init();
39 }
40 
44  : FoldLink(t, oset, tv, av)
45 {
46  if (not classserver().isA(t, ARITHMETIC_LINK))
47  throw InvalidParamException(TRACE_INFO, "Expecting a ArithmeticLink");
48  init();
49 }
50 
54  : FoldLink(t, a, b, tv, av)
55 {
56  if (not classserver().isA(t, ARITHMETIC_LINK))
57  throw InvalidParamException(TRACE_INFO, "Expecting a ArithmeticLink");
58  init();
59 }
60 
62  : FoldLink(l)
63 {
64  Type tscope = l.getType();
65  if (not classserver().isA(tscope, ARITHMETIC_LINK))
66  throw InvalidParamException(TRACE_INFO, "Expecting a ArithmeticLink");
67  init();
68 }
69 
71 {
72  knild = std::numeric_limits<double>::quiet_NaN();
73 }
74 
75 // ===========================================================
88 {
89  Handle road(reorder());
91 
92  Handle red(alp->FoldLink::reduce());
93 
94  alp = ArithmeticLinkCast(red);
95  if (NULL == alp) return red;
96  return alp->reorder();
97 }
98 
99 // ============================================================
100 
114 {
115  HandleSeq vars;
116  HandleSeq exprs;
117  HandleSeq numbers;
118 
119  for (const Handle& h : _outgoing)
120  {
121  if (h->getType() == VARIABLE_NODE)
122  vars.push_back(h);
123  else if (h->getType() == NUMBER_NODE)
124  numbers.push_back(h);
125  else
126  exprs.push_back(h);
127  }
128 
130  for (const Handle& h : vars) result.push_back(h);
131  for (const Handle& h : exprs) result.push_back(h);
132  for (const Handle& h : numbers) result.push_back(h);
133 
134  Handle h(FunctionLink::factory(getType(), result));
135  if (NULL == _atomTable) return h;
136 
137  return _atomTable->getAtomSpace()->add_atom(h);
138 }
139 
140 // ===========================================================
141 
148 static inline double get_double(AtomSpace *as, Handle h)
149 {
151  if (nnn == NULL)
152  throw RuntimeException(TRACE_INFO,
153  "Expecting a NumberNode, got %s",
154  classserver().getTypeName(h->getType()).c_str());
155 
156  return nnn->get_value();
157 }
158 
160 {
161  // XXX FIXME, we really want the instantiator to do the work
162  // here, but there is a giant circular-shared-library mess
163  // that results if we do this. So i'm disablig for now.
164 #ifdef CIRCULAR_SHARED_LIBS
165  Instantiator inst(as);
166 #endif
167  double sum = knild;
168  for (Handle h: _outgoing)
169  {
170 #ifdef CIRCULAR_SHARED_LIBS
171  h = inst.execute(h);
172 #else
174 
175  // Arghh. The cast should have been enough, but we currently
176  // can't store these in the atomsapce, due to circular shared
177  // lib dependencies.
178  if (NULL == flp and classserver().isA(h->getType(), FUNCTION_LINK))
180  if (NULL != flp)
181  h = flp->execute();
182 #endif
183  sum = konsd(sum, get_double(as, h));
184  }
185 
186  if (as) return as->add_atom(createNumberNode(sum));
187  return Handle(createNumberNode(sum));
188 }
189 // ===========================================================
AtomSpace * getAtomSpace(void)
Definition: AtomTable.h:166
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< FunctionLink > FunctionLinkPtr
Definition: FunctionLink.h:78
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
Definition: ClassServer.cc:159
std::shared_ptr< NumberNode > NumberNodePtr
Definition: NumberNode.h:76
std::shared_ptr< ArithmeticLink > ArithmeticLinkPtr
static FunctionLinkPtr FunctionLinkCast(const Handle &h)
Definition: FunctionLink.h:79
static LinkPtr LinkCast(const Handle &h)
Definition: Link.h:263
static NumberNodePtr NumberNodeCast(const Handle &h)
Definition: NumberNode.h:77
Handle execute(const Handle &expr)
Definition: Instantiator.h:70
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40
#define createNumberNode
Definition: NumberNode.h:83
static ArithmeticLinkPtr ArithmeticLinkCast(const Handle &h)
AtomTable * _atomTable
Definition: Atom.h:94
Handle add_atom(AtomPtr atom, bool async=false)
Definition: AtomSpace.cc:100