private bool MatchesAssignment()

in libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/AdaptiveDialog.cs [1312:1454]


        private bool MatchesAssignment(EntityInfo entity, EntityAssignment assignment)
         => (entity.Operation == null || entity.Operation == assignment.Operation)
            && (entity.Property == null || entity.Property == assignment.Property);

        // Generate candidate assignments including property and operation
        private IEnumerable<EntityAssignment> Candidates(Dictionary<string, List<EntityInfo>> entities, string[] expected, string lastEvent, EntityAssignment nextAssignment, JObject askDefault, JObject dialogDefault)
        {
            var globalExpectedOnly = dialogSchema.Schema[ExpectedOnlyKey]?.ToObject<List<string>>() ?? new List<string>();
            var requiresValue = dialogSchema.Schema[RequiresValueKey]?.ToObject<List<string>>() ?? new List<string>();
            var assignments = new List<EntityAssignment>();

            // Add entities with a recognized property
            foreach (var alternatives in entities.Values)
            {
                foreach (var alternative in alternatives)
                {
                    if (alternative.Property != null && (alternative.Value != null || !requiresValue.Contains(alternative.Operation)))
                    {
                        assignments.Add(new EntityAssignment
                        {
                            Value = alternative,
                            Property = alternative.Property,
                            Operation = alternative.Operation,
                            IsExpected = expected.Contains(alternative.Property)
                        });
                    }
                }
            }

            // Find possible mappings for entities without a property or where property entities are expected
            foreach (var propSchema in dialogSchema.Property.Children)
            {
                var isExpected = expected.Contains(propSchema.Name);
                var expectedOnly = propSchema.ExpectedOnly ?? globalExpectedOnly;
                foreach (var propEntity in propSchema.Entities)
                {
                    var entityName = StripProperty(propEntity);
                    if (entities.TryGetValue(entityName, out var matches) && (isExpected || !expectedOnly.Contains(entityName)))
                    {
                        foreach (var entity in matches)
                        {
                            if (entity.Property == null)
                            {
                                assignments.Add(new EntityAssignment
                                {
                                    Value = entity,
                                    Property = propSchema.Name,
                                    Operation = entity.Operation,
                                    IsExpected = isExpected
                                });
                            }
                            else if (entity.Property == entityName && entity.Value == null && entity.Operation == null && isExpected)
                            {
                                // Recast property with no value as match for property entities
                                assignments.Add(new EntityAssignment
                                {
                                    Value = entity,
                                    Property = propSchema.Name,
                                    Operation = null,
                                    IsExpected = isExpected,
                                });
                            }
                        }
                    }
                }
            }

            // Add default operations
            foreach (var assignment in assignments)
            {
                if (assignment.Operation == null)
                {
                    // Assign missing operation
                    if (lastEvent == AdaptiveEvents.ChooseEntity
                        && assignment.Value.Property == nextAssignment.Property)
                    {
                        // Property and value match ambiguous entity
                        assignment.Operation = AdaptiveEvents.ChooseEntity;
                        assignment.IsExpected = true;
                    }
                    else
                    {
                        // Assign default operator
                        assignment.Operation = DefaultOperation(assignment, askDefault, dialogDefault);
                    }
                }
            }

            // Add choose property matches
            if (lastEvent == AdaptiveEvents.ChooseProperty)
            {
                foreach (var alternatives in entities.Values)
                {
                    foreach (var alternative in alternatives)
                    {
                        if (alternative.Value == null)
                        {
                            // If alternative matches one alternative it answers chooseProperty
                            var matches = nextAssignment.Alternatives.Where(a => MatchesAssignment(alternative, a));
                            if (matches.Count() == 1)
                            {
                                assignments.Add(new EntityAssignment
                                {
                                    Value = alternative,
                                    Operation = AdaptiveEvents.ChooseProperty,
                                    IsExpected = true
                                });
                            }
                        }
                    }
                }
            }

            // Add pure operations
            foreach (var alternatives in entities.Values)
            {
                foreach (var alternative in alternatives)
                {
                    if (alternative.Operation != null && alternative.Property == null && alternative.Value == null)
                    {
                        var assignment = new EntityAssignment
                        {
                            Value = alternative,
                            Property = null,
                            Operation = alternative.Operation,
                            IsExpected = false
                        };
                        assignments.Add(assignment);
                    }
                }
            }

            // Preserve expectedProperties if there is no property
            foreach (var assignment in assignments)
            {
                if (assignment.Property == null)
                {
                    assignment.ExpectedProperties = expected.ToList();
                }
            }

            return assignments;
        }