private term(TermKind kind, atom a) { Kind = kind; _atom = a; _applyF = new Box <term>(default(term)); _applyX = new Box <term>(default(term)); }
public ClueId CreateClue(atom kind, ClueSource source, ClueConstant constant, params ClueId[] dependsOn) { foreach (var other in dependsOn) { if (other == null) { throw new Exception("null is not a clue that you can depend on"); } if (!_clueKind.ContainsKey(other)) { throw new Exception("can't depend on a clue that doesn't exist"); } } var id = _clueIdGen.GenerateClueId(kind); _clueKind[id] = kind; _clueSource[id] = source; _clueConstant[id] = constant; _clueDependsOn[id] = dependsOn.ToArray(); foreach (var other in dependsOn) { _cluesDependingOn[other].Add(id); } _cluesDependingOn[id] = new HashSet <ClueId>(); _clueBestKnownType[id] = types.MostGeneral; _clueErrors[id] = new List <InferenceError>(); _cluesToUpdate.Add(id); return(id); }
private term(term t1, term t2) { Kind = TermKind.Apply; _atom = default(atom); _applyF = new Box <term>(t1); _applyX = new Box <term>(t2); }
public A Generate <A>(atom prefix, Func <atom, int, int, A> build) { int count; if (!_counter.TryGetValue(prefix, out count)) { count = 0; } return(build(prefix, _counter[prefix] = ++count, ++_absolute)); }
public A Generate <A>(atom name, Func <atom, int, int, A> build) { if (_alreadyAssignedCount.ContainsKey(name)) { return(build(name, _alreadyAssignedCount[name], _alreadyAssignedAbs[name])); } return(_generator.Generate(name, (p, n, abs) => { _alreadyAssignedCount[p] = n; _alreadyAssignedAbs[p] = abs; return build(p, n, abs); })); }
// true: occurs check passed (meaning var doesn't occur) // doesn't produce output beyond "occurs check failed" to avoid generating loads of garbage // *except when it follows a variable* private bool OccursCheck(atom var, term t2) { if (Failed) { throw new Exception("this Vars failed and is in an invalid state"); } switch (t2.Kind) { case TermKind.Atom: return(true); case TermKind.Apply: OccursCheck(var, t2.ApplyF); if (Failed) { return(false); } OccursCheck(var, t2.ApplyX); if (Failed) { return(false); } return(true); case TermKind.Var: if (var == t2.VarName) { FailMessage(() => "occurs check failed"); return(false); } term bound; if (_bindings.TryGetValue(t2.VarName, out bound)) { OccursCheck(var, bound); FailMessage(() => $"when resolving {t2.VarName} to {bound}"); return(false); } return(true); } throw new Exception("unreachable case"); }
public static term Var(atom a) => new term(TermKind.Var, a);
public static term Atom(atom a) => new term(TermKind.Atom, a);
public static type Var(atom a) => new type(new term[0], term.Var(a));
public static type Atom(atom a) => new type(new term[0], term.Atom(a));
public ClueId GenerateClueId(atom name) => Generate(name, (p, n, abs) => new ClueId(p, n, abs));
public ClueId GenerateClueId(atom prefix) => Generate(prefix, (p, n, abs) => new ClueId(p, n, abs));
public bool Equals(atom other) { return(string.Equals(Value, other.Value)); }