/// <summary> /// Transform constrains state to array state /// </summary> public static StateArray TransformToArrayOrNull(object descNodeName, ConstrainsState descendant) { if (descendant.NoConstrains) { var constrains = new ConstrainsState(); var eName = "e" + descNodeName.ToString().ToLower() + "'"; var node = TicNode.CreateTypeVariableNode(eName, constrains); return(new StateArray(node)); } else if (descendant.HasDescendant && descendant.Descedant is StateArray arrayEDesc) { if (arrayEDesc.Element is StateRefTo) { var origin = arrayEDesc.ElementNode.GetNonReference(); if (origin.IsSolved) { return(new StateArray(origin)); } } else if (arrayEDesc.ElementNode.IsSolved) { return(arrayEDesc); } } return(null); }
/// <summary> /// Transform constrains to fun state /// </summary> public static StateFun TransformToFunOrNull(object descNodeName, ConstrainsState descendant, StateFun ancestor) { if (descendant.NoConstrains) { var argNodes = new TicNode[ancestor.ArgsCount]; for (int i = 0; i < ancestor.ArgsCount; i++) { var argNode = TicNode.CreateTypeVariableNode("a'" + descNodeName + "'" + i, new ConstrainsState()); argNode.AddAncestor(ancestor.ArgNodes[i]); argNodes[i] = argNode; } var retNode = TicNode.CreateTypeVariableNode("r'" + descNodeName, new ConstrainsState()); retNode.AddAncestor(ancestor.RetNode); return(StateFun.Of(argNodes, retNode)); } if (descendant.Descedant is StateFun funDesc && funDesc.ArgsCount == ancestor.ArgsCount) { if (funDesc.IsSolved) { return(funDesc); } // For perfomance bool allArgsAreSolved = true; var nrArgNodes = new TicNode[funDesc.ArgNodes.Length]; for (int i = 0; i < funDesc.ArgNodes.Length; i++) { nrArgNodes[i] = funDesc.ArgNodes[i].GetNonReference(); allArgsAreSolved = allArgsAreSolved && nrArgNodes[i].IsSolved; } var nrRetNode = funDesc.RetNode.GetNonReference(); if (allArgsAreSolved && nrRetNode.IsSolved) { return(StateFun.Of(nrArgNodes, nrRetNode)); } } return(null); }