public static string GetSummary(CallResolution resolution, bool technicalMistakeWasMade) { if (CallResolution.CallerHangUp == resolution) { return(HangUpSummaries.Random()); } if (CallResolution.Reject == resolution && technicalMistakeWasMade) { return(WronglyRejectedSummaries.Random()); } if (CallResolution.Reject == resolution && !technicalMistakeWasMade) { return(RejectedSummaries.Random()); } if (CallResolution.ApproveReplacement == resolution && technicalMistakeWasMade) { return(WronglyApprovedReplacement.Random()); } if (CallResolution.ApproveReplacement == resolution && !technicalMistakeWasMade) { return(ApprovedReplacement.Random()); } if (CallResolution.ApproveReturn == resolution && technicalMistakeWasMade) { return(WronglyApprovedReturns.Random()); } if (CallResolution.ApproveReturn == resolution && !technicalMistakeWasMade) { return(ApprovedReturns.Random()); } throw new ArgumentException("Invalid Call Resolution"); }
public Call(Chat chat, CallScenario scenario, CallResolution correctResolution, List <ICallOption> options) { _activePolicies = CurrentGameState.State.ActivePolicies; Chat = chat; Scenario = scenario; _correctResolution = correctResolution; Options = options; CurrentScene.Add(this); World.Subscribe(EventSubscription.Create <CallResolved>(ResolveCall, this)); }
private static Call Create(Action <Chat, CallScenario> scriptBuilder, CallResolution requestedOption) { var correctResolution = Rng.Between(requestedOption, CallResolution.Reject, 0.70); var scenario = CallScenarioFactory.Create(Job.ReturnSpecialistLevel1, PatienceLevel.Random); var chat = InitChat(scenario); scriptBuilder(chat, scenario); AddPlayerRequestConfirmation(scenario); var purchase = CreatePurchase(scenario, correctResolution); Debug.WriteLine($"CallResolution: Requested {requestedOption}. Expects {correctResolution} for {purchase.ProductName}"); var history = Purchase.CreateInfiniteWith(purchase).Take(1000).Where(x => x.PurchasedWithinLast(90)); scenario.Purchases = history; scenario.Target = new Optional <Purchase>(purchase); return(new Call(chat, scenario, correctResolution, Level1Options)); }
private static Purchase CreatePurchase(CallScenario scenario, CallResolution correctResolution) { var policies = CurrentGameState.State.ActivePolicies; Purchase purchase; int numAttempts = 0; while (true) { numAttempts++; purchase = Purchase.Create(DateWithinDays(90), scenario.Product); var call = new ResolvedCall(new Optional <Purchase>(purchase), correctResolution, correctResolution); var violations = policies.GetViolations(correctResolution, call); if (!violations.Any() || correctResolution == CallResolution.Reject) { break; } } scenario.Target = new Optional <Purchase>(purchase); Debug.WriteLine($"Created target purchase in {numAttempts} attempts"); return(purchase); }
public CallResolved(CallResolution resolution) { Resolution = resolution; }
private bool Applies(CallResolution resolution) { return(resolution.Equals(CallResolution.Any) || _resolutions.Contains(resolution)); }
public bool MeetsPolicy(CallResolution resolution, ResolvedCall call) { return(!Applies(resolution) || _condition(call)); }
public List <Policy> GetViolations(CallResolution resolution, ResolvedCall call) { return(_policies.Where(x => !x.MeetsPolicy(resolution, call)).ToList()); }
public void Evaluate(ComputationContext ctx) { if (this.Evaluation == null) { // trap only lambdas, name reference is a call, not passing function around // for example here trapping lambda into closure is necessary // ((x) => x*x)() // and here is not (regular call) // f() if (this.TrapLambdaClosure(ctx, ref this.callee)) { ConvertToExplicitInvoke(ctx); } { EntityInstance eval = this.Callee.Evaluation.Components.Cast <EntityInstance>(); this.Callee.DereferencedCount_LEGACY = ctx.Env.DereferencedOnce(eval, out IEntityInstance __eval, out bool via_pointer) ? 1 : 0; this.DereferencingCount = this.Callee.DereferencedCount_LEGACY; if (this.Callee.DereferencedCount_LEGACY > 0) { eval = __eval.Cast <EntityInstance>(); } if (!(this.Name.Binding.Match.Instance.Target is FunctionDefinition) && eval.Target.Cast <TypeDefinition>().InvokeFunctions().Any()) { // if we call a "closure", like my_closure() it is implicit calling "invoke" // so make it explicit on the fly ConvertToExplicitInvoke(ctx); } } IEnumerable <EntityInstance> matches = this.Name.Binding.Matches .Select(it => { if (it.Instance.Target.IsFunction()) { return(it.Instance); } else if (it.Instance.Target is Property prop) { return(prop.Getter?.InstanceOf?.TranslateThrough(it.Instance)); } else { return(null); } }) .Where(it => it != null); if (!matches.Any()) { this.resolution = new Option <CallResolution>(null); if (!this.Callee.Evaluation.Components.IsJoker) // do not cascade errors { ctx.AddError(ErrorCode.NotFunctionType, this.Callee); } } else { IEnumerable <CallResolution> targets = matches .Select(it => CallResolution.Create(ctx, this.Name.TemplateArguments, this, createCallContext(ctx, this.Name, it.TargetFunction), targetFunctionInstance: it)) .Where(it => it != null) .StoreReadOnly(); targets = targets.Where(it => it.RequiredParametersUsed()).StoreReadOnly(); targets = targets.Where(it => it.CorrectlyFormedArguments()).StoreReadOnly(); targets = targets.Where(it => it.ArgumentTypesMatchParameters(ctx)).StoreReadOnly(); if (this.RequestedOutcomeTypeName != null) { targets = targets.Where(it => it.OutcomeMatchesRequest(ctx)).StoreReadOnly(); } targets = resolveOverloading(targets).StoreReadOnly(); this.resolution = new Option <CallResolution>(targets.FirstOrDefault()); if (!targets.Any()) { ctx.AddError(ErrorCode.TargetFunctionNotFound, this); } else { if (targets.Count() > 1) { ctx.ErrorManager.AddError(ErrorCode.NOTEST_AmbiguousOverloadedCall, this, targets.Select(it => it.TargetFunctionInstance.Target)); } foreach (var group in this.Resolution.GetArgumentsMultipleTargeted()) { // we only report second "override" because if there are more // it is more likely user forgot to mark parameter variadic ctx.ErrorManager.AddError(ErrorCode.ArgumentForFunctionAlreadyGiven, group.Skip(1).FirstOrDefault()); } foreach (FunctionParameter param in this.Resolution.GetUnfulfilledVariadicParameters()) { ctx.ErrorManager.AddError(ErrorCode.InvalidNumberVariadicArguments, this, param); } if (targets.Count() == 1) { this.Resolution.EnhanceArguments(ctx); } this.Resolution.SetMappings(ctx); // filtering here is a bit shaky -- if we don't use type inference // we have to filter by what we bind to, but if we use inference // we use target instance (functor or function, not a variable) because only it // is altered by type inference if (this.Resolution.InferredTemplateArguments == null) { // leave only binding which was used for mapping this.Name.Binding.Filter(it => it.IsIdentical(this.Resolution.TargetFunctionInstance)); } else { NameReference this_name = this.Name; this_name.DetachFrom(this); this.callee = this_name.Recreate(this.Resolution.InferredTemplateArguments .Select(it => new TemplateArgument(it)), this.Resolution.TargetFunctionInstance, this_name.Binding.Match.IsLocal); this.callee.AttachTo(this); this.Callee.Evaluated(ctx, EvaluationCall.AdHocCrossJump); if (!this.Name.Binding.HasMatch) { throw new Exception("We've just lost our binding, probably something wrong with template translations"); } } this.Evaluation = this.Resolution.Evaluation; if (ctx.Env.IsReferenceOfType(this.Evaluation.Aggregate)) { // basically we are saying that the outcome of the function has the lifetime // equal to the shortest lifetime of arguments // or local if the function has not arguments at all Lifetime lifetime = null; foreach (FunctionArgument arg in this.Resolution.ActualArguments) { // todo: we should check if the expression is not passed implictly by reference if (arg == this.Resolution.MetaThisArgument || ctx.Env.IsReferenceOfType(arg.Evaluation.Aggregate)) { lifetime = arg.Evaluation.Aggregate.Lifetime.Shorter(lifetime); } } if (lifetime == null) { lifetime = Lifetime.Create(this); } if (this.Evaluation.Aggregate.Lifetime != lifetime) { this.Evaluation = EvaluationInfo.Create( this.Evaluation.Components.Rebuild(ctx, lifetime, deep: false), this.Evaluation.Aggregate.Build(lifetime)); } } } } if (this.Evaluation == null) { this.Evaluation = Environment.JokerEval; } foreach (IExpression arg in UserArguments) { arg.ValidateValueExpression(ctx); } } }
public CallResolutionOption(CallResolution resolution, string description) { _resolution = resolution; Description = description; }
private void OnCallResolved(CallResolution resolution) { _resolution = resolution; _label.Text = CallSummaries.GetSummary(_resolution, _technicalMistakeMade); }
public ResolvedCall(Optional <Purchase> purchase, CallResolution correct, CallResolution selected) { Purchase = purchase; CorrectResolution = correct; SelectedResolution = selected; }