LightJason - AgentSpeak(L++)
CUnifier.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.unify;
25 
35 
36 import javax.annotation.Nonnull;
37 import java.text.MessageFormat;
38 import java.util.Collections;
39 import java.util.HashSet;
40 import java.util.LinkedList;
41 import java.util.List;
42 import java.util.Set;
43 import java.util.stream.Collectors;
44 import java.util.stream.Stream;
45 
46 
50 public final class CUnifier implements IUnifier
51 {
55  private final IAlgorithm m_hashbased;
59  private final IAlgorithm m_recursive;
60 
64  public CUnifier()
65  {
66  this( new CHash(), new CRecursive() );
67  }
68 
75  public CUnifier( @Nonnull final IUnifier.IAlgorithm p_hashbased, @Nonnull final IUnifier.IAlgorithm p_recursive )
76  {
77  m_hashbased = p_hashbased;
78  m_recursive = p_recursive;
79  }
80 
81  // --- inheritance & context modification ------------------------------------------------------------------------------------------------------------------
82 
83  @Nonnull
84  @Override
85  public final Set<IVariable<?>> unify( @Nonnull final ILiteral p_source, @Nonnull final ILiteral p_target )
86  {
87  final Set<IVariable<?>> l_result = new HashSet<>();
88 
89  // try to unify exact or if not possible by recursive on the value set
90  if ( !(
91  p_target.structurehash() == p_source.structurehash()
92  ? m_hashbased.unify(
93  l_result,
94  CCommon.flattenrecursive( p_source.orderedvalues() ),
95  CCommon.flattenrecursive( p_target.orderedvalues() )
96  )
97  : m_recursive.unify(
98  l_result,
99  p_source.orderedvalues(),
100  p_target.orderedvalues()
101  ) ) )
102  return Collections.emptySet();
103 
104  return l_result;
105  }
106 
107  @Nonnull
108  @Override
109  public IFuzzyValue<Boolean> unify( @Nonnull final IContext p_context, @Nonnull final ILiteral p_literal, final long p_variables,
110  @Nonnull final IExpression p_expression, final boolean p_parallel )
111  {
112  // get all possible variables
113  final List<Set<IVariable<?>>> l_variables = this.variables( p_context.agent(), p_literal, p_variables );
114  if ( l_variables.isEmpty() )
115  return CFuzzyValue.from( false );
116 
117  // otherwise the expression must be checked, first match will be used
118  final Set<IVariable<?>> l_result = parallelstream( l_variables.stream(), p_parallel )
119  .filter( i -> evaluateexpression( p_context, p_expression, i ) )
120  .findFirst()
121  .orElse( Collections.emptySet() );
122 
123  // if no match
124  if ( l_result.isEmpty() )
125  return CFuzzyValue.from( false );
126 
127  CCommon.updatecontext( p_context, l_result.stream() );
128  return CFuzzyValue.from( true );
129  }
130 
131  // ---------------------------------------------------------------------------------------------------------------------------------------------------------
132 
133  @Override
134  public final int hashCode()
135  {
136  return m_hashbased.hashCode() ^ m_recursive.hashCode();
137  }
138 
139 
140  @Override
141  public final boolean equals( final Object p_object )
142  {
143  return ( p_object instanceof IUnifier ) && ( this.hashCode() == p_object.hashCode() );
144  }
145 
146  @Override
147  public final String toString()
148  {
149  return MessageFormat.format( "hash-based unification: {0} / recursive unification: {1}", m_hashbased, m_recursive );
150  }
151 
160  private static <T> Stream<T> parallelstream( final Stream<T> p_stream, final boolean p_parallel )
161  {
162  return p_parallel ? p_stream.parallel() : p_stream;
163  }
164 
173  private static boolean evaluateexpression( final IContext p_context, final IExpression p_expression, final Set<IVariable<?>> p_variables )
174  {
175  final List<ITerm> l_return = new LinkedList<>();
176  p_expression.execute(
177  false, CCommon.updatecontext( p_context.duplicate(), p_variables.stream() ),
178  Collections.emptyList(),
179  l_return
180  );
181 
182  return ( l_return.size() == 1 ) && ( l_return.get( 0 ).<Boolean>raw() );
183  }
184 
193  private List<Set<IVariable<?>>> variables( final IAgent<?> p_agent, final ILiteral p_literal, final long p_variablenumber )
194  {
195  return p_agent.beliefbase()
196  .stream( p_literal.negated(), p_literal.fqnfunctor() )
197  .filter( i -> i.emptyValues() == p_literal.emptyValues() )
198  .map( i -> this.unify( i, p_literal.deepcopy().<ILiteral>raw() ) )
199  .filter( i -> p_variablenumber == i.size() )
200  .collect( Collectors.toList() );
201  }
202 }
List< Set< IVariable<?> > > variables(final IAgent<?> p_agent, final ILiteral p_literal, final long p_variablenumber)
search all relevant literals within the agent beliefbase and unifies the variables ...
Definition: CUnifier.java:193
< T extends ITerm > boolean unify(final Set< IVariable<?>> p_variables, final Stream< T > p_source, final Stream< T > p_target)
unify algorithm
final IAlgorithm m_recursive
recursive unify algorithm
Definition: CUnifier.java:59
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
final IAlgorithm m_hashbased
hash-based unify algorithm
Definition: CUnifier.java:55
static< N > IFuzzyValue< N > from( @Nonnull final N p_value)
factory
common structure for execution definition
interface of an unification algorithm
Definition: IUnifier.java:43
Stream< ILiteral > stream( @Nullable final IPath... p_path)
returns stream of literal
CUnifier( @Nonnull final IUnifier.IAlgorithm p_hashbased, @Nonnull final IUnifier.IAlgorithm p_recursive)
ctor
Definition: CUnifier.java:75
static Stream< ITerm > flattenrecursive( @Nonnull final Stream< ITerm > p_input)
recursive stream of term values
IPath fqnfunctor()
returns the full-qualified functor with path and name
execution context with local data
Definition: IContext.java:42
final boolean equals(final Object p_object)
Definition: CUnifier.java:141
boolean emptyValues()
check for empty values
static IContext updatecontext( @Nonnull final IContext p_context, @Nonnull final Stream< IVariable<?>> p_unifiedvariables)
updates within an instance context all variables of the stream
static< T > Stream< T > parallelstream(final Stream< T > p_stream, final boolean p_parallel)
execute stream in parallel
Definition: CUnifier.java:160
result for an immutable fuzzy value
boolean negated()
getter of the literal for the negation
final Set< IVariable<?> > unify( @Nonnull final ILiteral p_source, @Nonnull final ILiteral p_target)
unifies a literal
Definition: CUnifier.java:85
T deepcopy( @Nullable final IPath... p_prefix)
clones the object (shallow-copy)
IFuzzyValue< Boolean > unify( @Nonnull final IContext p_context, @Nonnull final ILiteral p_literal, final long p_variables, @Nonnull final IExpression p_expression, final boolean p_parallel)
unifies the literal with the expression
Definition: CUnifier.java:109
IView beliefbase()
returns the beliefbase
IContext duplicate()
duplicates the context with a shallow-copy
static boolean evaluateexpression(final IContext p_context, final IExpression p_expression, final Set< IVariable<?>> p_variables)
evaluate expression
Definition: CUnifier.java:173