<commit_before>class TypeClash extends Error {
    constructor(type, value) {
        super();

        this.type = type;
        this.value = value;
    }

    toString() {
        return `Runtime type assertion failure: Expected ${this.type.toString()}', got '${JSON.stringify(this.value)}'.`;
    }
}

class Constraint {
    constructor(lower, upper) {
        this.lower = lower;
        this.upper = upper;
    }

    equals(that) {
        if (that instanceof Constraint) {
            return this.lower.equals(that.lower) && this.upper.equals(that.upper);
        }

        return false;
    }

    toString() {
        return this.lower.toString() + ' <= ' + this.upper.toString();
    }

    isUseless() {
        return this.lower.equals(this.upper) || this.upper instanceof TopType;
    }

    isConsistent() {
        var a = this.lower;
        var b = this.upper;

        if (a instanceof NamedType || a instanceof SumType) {
            if (b instanceof NamedType || b instanceof SumType) {
                var na = (a instanceof NamedType) ? [a] : a.names;
                var nb = (b instanceof NamedType) ? [b] : b.names;

                return na.every(t1 => nb.some(t2 => t1.equals(t2)));
            }
        }

        if (a instanceof ArrayType       && b instanceof ArrayType)       return true;
        if (a instanceof TupleType       && b instanceof TupleType)       return b.types.length <= a.types.length;
        if (a instanceof TaggedUnionType && b instanceof TaggedUnionType) return a.keys.every(k => b.keys.indexOf(k) >= 0);
        if (a instanceof RecordType      && b instanceof RecordType)      return b.keys.every(k => a.keys.indexOf(k) >= 0);

        return (b instanceof TopType) || a.isParam() || b.isParam();
    }

    unary() {
        if (this.lower instanceof ArrayType && this.upper instanceof ArrayType) {
            return [new Constraint(this.lower.type, this.upper.type)];
        }

        if (this.lower instanceof TupleType && this.upper instanceof TupleType) {
            return this.upper.types.map((t, i) => new Constraint(this.lower.types[i], t));
        }

        if (this.lower instanceof TaggedUnionType && this.upper instanceof TaggedUnionType) {
            return this.lower.keys.map(k => new Constraint(this.lower.vals[k], this.upper.vals[k]));
        }

        if (this.lower instanceof RecordType && this.upper instanceof RecordType) {
            return this.upper.keys.map(k => new Constraint(this.lower.vals[k], this.upper.vals[k]));
        }

        return [];
    }

    binary(that) {
        if (this.upper.equals(that.lower)) {
            return [new Constraint(this.lower, that.upper)];
        }

        if (this.lower.equals(that.upper)) {
            return [new Constraint(that.lower, this.upper)];
        }

        return [];
    }
}

class ConstraintSet {
    constructor(constraints) {
        this.constraints = constraints.filter(c => !c.isUseless());
        var inconsistent = constraints.filter(c => !c.isConsistent());

        if (inconsistent.length != 0) {
            throw new Error('Inconsistent constraints: [' + inconsistent.map(c => c.toString()).join(', ') + ']');
        }
    }
<commit_msg>(Closes #9) Repair bad assumptions in unary constraint generation function.<commit_after>class TypeClash extends Error {
    constructor(type, value) {
        super();

        this.type = type;
        this.value = value;
    }

    toString() {
        return `Runtime type assertion failure: Expected ${this.type.toString()}', got '${JSON.stringify(this.value)}'.`;
    }
}

class Constraint {
    constructor(lower, upper) {
        this.lower = lower;
        this.upper = upper;
    }

    equals(that) {
        if (that instanceof Constraint) {
            return this.lower.equals(that.lower) && this.upper.equals(that.upper);
        }

        return false;
    }

    toString() {
        return this.lower.toString() + ' <= ' + this.upper.toString();
    }

    isUseless() {
        return this.lower.equals(this.upper) || this.upper instanceof TopType;
    }

    isConsistent() {
        var a = this.lower;
        var b = this.upper;

        if (a instanceof NamedType || a instanceof SumType) {
            if (b instanceof NamedType || b instanceof SumType) {
                var na = (a instanceof NamedType) ? [a] : a.names;
                var nb = (b instanceof NamedType) ? [b] : b.names;

                return na.every(t1 => nb.some(t2 => t1.equals(t2)));
            }
        }

        if (a instanceof ArrayType       && b instanceof ArrayType)       return true;
        if (a instanceof TupleType       && b instanceof TupleType)       return b.types.length <= a.types.length;
        if (a instanceof TaggedUnionType && b instanceof TaggedUnionType) return a.keys.every(k => b.keys.indexOf(k) >= 0);
        if (a instanceof RecordType      && b instanceof RecordType)      return b.keys.every(k => a.keys.indexOf(k) >= 0);

        return (b instanceof TopType) || a.isParam() || b.isParam();
    }

    unary() {
        if (this.lower instanceof ArrayType && this.upper instanceof ArrayType) {
            return [new Constraint(this.lower.type, this.upper.type)];
        }

        if (this.lower instanceof TupleType && this.upper instanceof TupleType) {
            return this.upper.types.filter((t, i) => i < this.lower.types.length).map((t, i) => new Constraint(this.lower.types[i], t));
        }

        if (this.lower instanceof TaggedUnionType && this.upper instanceof TaggedUnionType) {
            return this.lower.keys.filter(k => this.upper.keys.indexOf(k) >= 0).map(k => new Constraint(this.lower.vals[k], this.upper.vals[k]));
        }

        if (this.lower instanceof RecordType && this.upper instanceof RecordType) {
            return this.upper.keys.filter(k => this.lower.keys.indexOf(k) >= 0).map(k => new Constraint(this.lower.vals[k], this.upper.vals[k]));
        }

        return [];
    }

    binary(that) {
        if (this.upper.equals(that.lower)) {
            return [new Constraint(this.lower, that.upper)];
        }

        if (this.lower.equals(that.upper)) {
            return [new Constraint(that.lower, this.upper)];
        }

        return [];
    }
}

class ConstraintSet {
    constructor(constraints) {
        this.constraints = constraints.filter(c => !c.isUseless());
        var inconsistent = constraints.filter(c => !c.isConsistent());

        if (inconsistent.length != 0) {
            throw new Error('Inconsistent constraints: [' + inconsistent.map(c => c.toString()).join(', ') + ']');
        }
    }

{'fraction_non_alphanumeric': 0.13806646525679758, 'fraction_numerical': 0.00256797583081571, 'mean_word_length': 2.1923818707810994, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5351957', 'n_tokens_mistral': 1988, 'n_tokens_neox': 1919, 'n_words': 452}