001/*
002 * Java Genetic Algorithm Library (jenetics-8.1.0).
003 * Copyright (c) 2007-2024 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020package io.jenetics.ext.rewriting;
021
022import static java.util.Objects.requireNonNull;
023import static io.jenetics.internal.util.Hashes.hash;
024
025import java.util.Map;
026
027import io.jenetics.ext.rewriting.TreePattern.Var;
028import io.jenetics.ext.util.Tree;
029
030/**
031 * The result of a tree match operation. It contains the matching tree and the
032 * tree variables which matches the matching tree.
033 *
034 * {@snippet lang="java":
035 * final Tree<String, ?> tree = null; // @replace substring='null' replacement="..."
036 * final TreePattern<String> pattern = null; // @replace substring='null' replacement="..."
037 * final Optional<TreeMatchResult<String>> result = pattern.match(tree);
038 * result.ifPresent(r -> {assert r.tree() == tree;});
039 * }
040 *
041 * @see TreePattern#match(Tree)
042 *
043 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
044 * @version 5.0
045 * @since 5.0
046 */
047public final class TreeMatchResult<V> {
048
049        private final Tree<V, ?> _tree;
050        private final Map<Var<V>, Tree<V, ?>> _vars;
051
052        private TreeMatchResult(
053                final Tree<V, ?> tree,
054                final Map<Var<V>, Tree<V, ?>> vars
055        ) {
056                _tree = requireNonNull(tree);
057                _vars = Map.copyOf(vars);
058        }
059
060        /**
061         * The node (tree), which has been matched by some pattern. This tree is the
062         * argument of the {@link TreePattern#match(Tree)} call, in the case of a
063         * match.
064         *
065         * {@snippet lang="java":
066         * final Tree<String, ?> tree = null; // @replace substring='null' replacement="..."
067         * final TreePattern<String> pattern = null; // @replace substring='null' replacement="..."
068         * final Optional<TreeMatchResult<String>> result = pattern.match(tree);
069         * result.ifPresent(r -> {assert r.tree() == tree;});
070         * }
071         *
072         * @return node (tree), which has been matched by some pattern
073         */
074        public Tree<V, ?> tree() {
075                return _tree;
076        }
077
078        /**
079         * The variables involved while matching the tree {@link #tree()}.
080         *
081         * @return variables involved while matching the tree {@link #tree()}.
082         */
083        public Map<Var<V>, Tree<V, ?>> vars() {
084                return _vars;
085        }
086
087        @Override
088        public int hashCode() {
089                return hash(_tree, hash(_vars));
090        }
091
092        @Override
093        public boolean equals(final Object obj) {
094                return obj == this ||
095                        obj instanceof TreeMatchResult<?> other &&
096                        _tree.equals(other._tree) &&
097                        _vars.equals(other._vars);
098        }
099
100        @Override
101        public String toString() {
102                return _tree.toParenthesesString();
103        }
104
105        static <V> TreeMatchResult<V> of(
106                final Tree<V, ?> tree,
107                final Map<Var<V>, Tree<V, ?>> vars
108        ) {
109                return new TreeMatchResult<>(tree, vars);
110        }
111
112}