LightJason - AgentSpeak(L++)
CProxyAction.java
Go to the documentation of this file.
1 /*
2  * @cond LICENSE
3  * ######################################################################################
4  * # LGPL License #
5  * # #
6  * # This file is part of the LightJason AgentSpeak(L++) #
7  * # Copyright (c) 2015-19, LightJason (info@lightjason.org) #
8  * # This program is free software: you can redistribute it and/or modify #
9  * # it under the terms of the GNU Lesser General Public License as #
10  * # published by the Free Software Foundation, either version 3 of the #
11  * # License, or (at your option) any later version. #
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 Lesser General Public License for more details. #
17  * # #
18  * # You should have received a copy of the GNU Lesser General Public License #
19  * # along with this program. If not, see http://www.gnu.org/licenses/ #
20  * ######################################################################################
21  * @endcond
22  */
23 
24 package org.lightjason.agentspeak.language.execution.action;
25 
26 import org.apache.commons.lang3.StringUtils;
38 
39 import javax.annotation.Nonnull;
40 import java.text.MessageFormat;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.LinkedList;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Objects;
47 import java.util.stream.Collectors;
48 import java.util.stream.IntStream;
49 import java.util.stream.Stream;
50 
51 
55 public final class CProxyAction implements IExecution
56 {
60  private static final long serialVersionUID = 4799005052331053271L;
64  private final IExecution m_execution;
65 
72  public CProxyAction( @Nonnull final Map<IPath, IAction> p_actions, @Nonnull final ILiteral p_literal )
73  {
74  m_execution = new CActionWrapper( p_literal, p_actions );
75  }
76 
77  @Nonnull
78  @Override
79  public final IFuzzyValue<Boolean> execute( final boolean p_parallel, @Nonnull final IContext p_context,
80  @Nonnull final List<ITerm> p_argument, @Nonnull final List<ITerm> p_return
81  )
82  {
83  return m_execution.execute( p_parallel, p_context, p_argument, p_return );
84  }
85 
86  @Nonnull
87  @Override
88  public final Stream<IVariable<?>> variables()
89  {
90  return m_execution.variables();
91  }
92 
93  @Override
94  public final String toString()
95  {
96  return MessageFormat.format( "{0}", m_execution );
97  }
98 
102  private static class CTermWrapper<T extends ITerm> implements IExecution
103  {
107  private static final long serialVersionUID = 6984535096829821628L;
111  private final T m_value;
112 
118  CTermWrapper( @Nonnull final T p_value )
119  {
120  m_value = p_value;
121  }
122 
123  @Override
124  public final int hashCode()
125  {
126  return m_value.hashCode();
127  }
128 
129  @Override
130  public final String toString()
131  {
132  return MessageFormat.format( "{0}", m_value );
133  }
134 
135  @Override
136  public final boolean equals( final Object p_object )
137  {
138  return ( p_object instanceof IExecution ) && ( this.hashCode() == p_object.hashCode() );
139  }
140 
141  @Nonnull
142  @Override
143  public final IFuzzyValue<Boolean> execute( final boolean p_parallel, @Nonnull final IContext p_context,
144  @Nonnull final List<ITerm> p_argument, @Nonnull final List<ITerm> p_return
145  )
146  {
147  p_return.add( m_value );
148  return CFuzzyValue.from( true );
149  }
150 
151  @Nonnull
152  @Override
153  public final Stream<IVariable<?>> variables()
154  {
155  return this.getVariableSet( m_value );
156  }
157 
164  @Nonnull
165  private Stream<IVariable<?>> getVariableSet( final T p_value )
166  {
167  return Stream.<IVariable<?>>empty();
168  }
169  }
170 
176  private static class CActionWrapper implements IExecution
177  {
181  private static final long serialVersionUID = 5531271525053969711L;
185  private final boolean m_parallel;
189  private final IAction m_action;
194  private final Map<Integer, IExecution> m_arguments;
195 
196 
203  CActionWrapper( @Nonnull final ILiteral p_literal, @Nonnull final Map<IPath, IAction> p_actions )
204  {
205  // check parallel and inner execution
206  m_parallel = p_literal.hasAt();
207 
208 
209  // resolve action
210  m_action = p_actions.get( p_literal.fqnfunctor() );
211  if ( Objects.isNull( m_action ) )
212  throw new CIllegalArgumentException( org.lightjason.agentspeak.common.CCommon.languagestring( this, "actionunknown", p_literal ) );
213 
214  // check number of arguments and add action to the score cache
215  if ( p_literal.orderedvalues().count() < m_action.minimalArgumentNumber() )
216  throw new CIllegalArgumentException(
217  org.lightjason.agentspeak.common.CCommon.languagestring( this, "argumentnumber", p_literal, m_action.minimalArgumentNumber() ) );
218 
219  // resolve action arguments
220  m_arguments = Collections.unmodifiableMap( this.createSubExecutions( p_literal.orderedvalues().collect( Collectors.toList() ), p_actions ) );
221  }
222 
223  @Override
224  public final int hashCode()
225  {
226  return m_action.hashCode() + m_arguments.hashCode();
227  }
228 
229  @Override
230  public final String toString()
231  {
232  return MessageFormat.format( "{0}({1})", m_action, StringUtils.join( m_arguments.values(), ", " ) );
233  }
234 
235  @Override
236  public final boolean equals( final Object p_object )
237  {
238  return ( p_object instanceof IExecution ) && ( this.hashCode() == p_object.hashCode() );
239  }
240 
241  @Nonnull
242  @Override
243  public IFuzzyValue<Boolean> execute( final boolean p_parallel, @Nonnull final IContext p_context,
244  @Nonnull final List<ITerm> p_argument, @Nonnull final List<ITerm> p_return
245  )
246  {
247  return m_action.execute(
248  m_parallel, p_context,
249  this.subexecute( p_context, m_arguments ),
250  p_return
251  );
252  }
253 
254  @Nonnull
255  @Override
256  public final Stream<IVariable<?>> variables()
257  {
258  return m_action.variables();
259  }
260 
268  @Nonnull
269  private Map<Integer, IExecution> createSubExecutions( @Nonnull final Collection<? extends ITerm> p_elements,
270  @Nonnull final Map<IPath, IAction> p_actions )
271  {
272  // convert collection to list and build map with indices
273  final List<? extends ITerm> l_elements = new LinkedList<>( p_elements );
274  return IntStream.range( 0, l_elements.size() )
275  .boxed()
276  .collect(
277  Collectors.toMap(
278  i -> i,
279  i ->
280  {
281  final ITerm l_term = l_elements.get( i );
282  return l_term instanceof ILiteral
283  ? new CActionWrapper( l_term.term(), p_actions )
284  : new CTermWrapper<>( l_term );
285  }
286  )
287  );
288  }
289 
297  @Nonnull
298  private List<ITerm> subexecute( @Nonnull final IContext p_context, @Nonnull final Map<Integer, IExecution> p_execution )
299  {
300  return Collections.unmodifiableList( CCommon.replaceFromContext(
301  p_context,
302  ( m_parallel
303  ? p_execution.entrySet().parallelStream()
304  : p_execution.entrySet()
305  .stream() )
306  .flatMap( i ->
307  {
308  final List<ITerm> l_return = new LinkedList<>();
309  i.getValue().execute( m_parallel, p_context, Collections.emptyList(), l_return );
310  return l_return.stream();
311  } )
312  .collect( Collectors.toList() )
313  ) );
314  }
315  }
316 
317 }
final Stream< IVariable<?> > variables()
returns a stream with all used variables
final Map< Integer, IExecution > m_arguments
arguments as map with index for prevent result order on parallel execution
IFuzzyValue< Boolean > execute(final boolean p_parallel, @Nonnull final IContext p_context, @Nonnull final List< ITerm > p_argument, @Nonnull final List< ITerm > p_return)
defines a plan-body operation
Stream< IVariable<?> > getVariableSet(final T p_value)
returns a variable set based on the generic type
Stream< IVariable<?> > variables()
returns a stream with all used variables
static< N > IFuzzyValue< N > from( @Nonnull final N p_value)
factory
final IFuzzyValue< Boolean > execute(final boolean p_parallel, @Nonnull final IContext p_context, @Nonnull final List< ITerm > p_argument, @Nonnull final List< ITerm > p_return)
defines a plan-body operation
common structure for execution definition
final IFuzzyValue< Boolean > execute(final boolean p_parallel, @Nonnull final IContext p_context, @Nonnull final List< ITerm > p_argument, @Nonnull final List< ITerm > p_return)
defines a plan-body operation
static< T > String languagestring(final T p_source, final String p_label, final Object... p_parameter)
returns the language depend string on any object
default Stream< IVariable<?> > variables()
returns a stream with all used variables
Definition: IAction.java:66
execution context with local data
Definition: IContext.java:42
external action interface
Definition: IAction.java:38
final Stream< IVariable<?> > variables()
returns a stream with all used variables
CActionWrapper( @Nonnull final ILiteral p_literal, @Nonnull final Map< IPath, IAction > p_actions)
ctor
CProxyAction( @Nonnull final Map< IPath, IAction > p_actions, @Nonnull final ILiteral p_literal)
ctor
result for an immutable fuzzy value
default int minimalArgumentNumber()
minimum number of arguments
Definition: IAction.java:59
Map< Integer, IExecution > createSubExecutions( @Nonnull final Collection<? extends ITerm > p_elements, @Nonnull final Map< IPath, IAction > p_actions)
builds the map of execution arguments
final Stream< IVariable<?> > variables()
returns a stream with all used variables
inner class for encapsulating term values (variable / raw terms)
IFuzzyValue< Boolean > execute(final boolean p_parallel, @Nonnull final IContext p_context, @Nonnull final List< ITerm > p_argument, @Nonnull final List< ITerm > p_return)
defines a plan-body operation
List< ITerm > subexecute( @Nonnull final IContext p_context, @Nonnull final Map< Integer, IExecution > p_execution)
execute inner structures