Skip to content

Commit

Permalink
Replace hard-coded type approximations with references to the new cla…
Browse files Browse the repository at this point in the history
…ss-based LitTypes.

PiperOrigin-RevId: 463636591
  • Loading branch information
cjqian authored and LIT team committed Jul 27, 2022
1 parent 3e8735b commit 8c6ac11
Show file tree
Hide file tree
Showing 36 changed files with 414 additions and 269 deletions.
10 changes: 5 additions & 5 deletions lit_nlp/api/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,26 +486,26 @@ class MultiFieldMatcher(LitType):


@attr.s(auto_attribs=True, frozen=True, kw_only=True)
class _Salience(LitType):
class Salience(LitType):
"""Metadata about a returned salience map."""
autorun: bool = False # If the saliency technique is automatically run.
signed: bool # If the returned values are signed.


@attr.s(auto_attribs=True, frozen=True, kw_only=True)
class TokenSalience(_Salience):
class TokenSalience(Salience):
"""Metadata about a returned token salience map."""
default: dtypes.TokenSalience = None


@attr.s(auto_attribs=True, frozen=True, kw_only=True)
class FeatureSalience(_Salience):
class FeatureSalience(Salience):
"""Metadata about a returned feature salience map."""
default: dtypes.FeatureSalience = None


@attr.s(auto_attribs=True, frozen=True, kw_only=True)
class ImageSalience(_Salience):
class ImageSalience(Salience):
"""Metadata about a returned image saliency.
The data is returned as an image in the base64 URL encoded format, e.g.,
Expand All @@ -515,7 +515,7 @@ class ImageSalience(_Salience):


@attr.s(auto_attribs=True, frozen=True, kw_only=True)
class SequenceSalience(_Salience):
class SequenceSalience(Salience):
"""Metadata about a returned sequence salience map."""
default: dtypes.SequenceSalienceMap = None

Expand Down
6 changes: 0 additions & 6 deletions lit_nlp/api/types_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@
from lit_nlp.api import types
from google3.testing.pybase import googletest

NUM_TYPES = 41


class TypesTest(googletest.TestCase):

def test_num_littypes(self):
num_types = len(types.all_littypes())
self.assertEqual(num_types, NUM_TYPES)

def test_inherit_parent_default_type(self):
lit_type = types.StringLitType()
self.assertIsInstance(lit_type.default, str)
Expand Down
69 changes: 37 additions & 32 deletions lit_nlp/client/elements/interpreter_controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
import './checkbox';
import '@material/mwc-icon';

import {property} from 'lit/decorators';
import {customElement} from 'lit/decorators';
import { html} from 'lit';
import {html} from 'lit';
import {customElement, property} from 'lit/decorators';
import {observable} from 'mobx';

import {ReactiveElement} from '../lib/elements';
import {CategoryLabel, FieldMatcher, LitType, LitTypeWithVocab, MultiFieldMatcher, Scalar, SparseMultilabel} from '../lib/lit_types';
import {styles as sharedStyles} from '../lib/shared_styles.css';
import {LitType, Spec} from '../lib/types';
import {Spec} from '../lib/types';
import {isLitSubtype} from '../lib/utils';

import {styles} from './interpreter_controls.css';
Expand Down Expand Up @@ -101,23 +101,25 @@ export class InterpreterControls extends ReactiveElement {
renderControls() {
const spec = this.spec as Spec;
return Object.keys(spec).map(name => {

// Ensure a default value for any of the options provided for setting.
if (this.settings[name] == null) {
if (isLitSubtype(spec[name], 'SparseMultilabel')) {
this.settings[name] = spec[name].default as string[];
if (spec[name] instanceof SparseMultilabel) {
this.settings[name] = (spec[name] as SparseMultilabel).default;
}
// If select all is True, default value is all of vocab.
if (isLitSubtype(spec[name], 'MultiFieldMatcher')) {
this.settings[name] = spec[name].select_all!?
spec[name].vocab as string[] :
spec[name].default as string[];
if (spec[name] instanceof MultiFieldMatcher) {
const fieldSpec = spec[name] as MultiFieldMatcher;
this.settings[name] = fieldSpec.select_all ?
fieldSpec.vocab as string[] :
fieldSpec.default;
}
// FieldMatcher has its vocab set outside of this element.
else if (isLitSubtype(spec[name], ['CategoryLabel', 'FieldMatcher'])) {
else if (
spec[name] instanceof CategoryLabel ||
spec[name] instanceof FieldMatcher) {
const {vocab} = spec[name] as LitTypeWithVocab;
this.settings[name] =
spec[name].vocab != null && spec[name].vocab!.length > 0 ?
spec[name].vocab![0] : '';
vocab != null && vocab.length > 0 ? vocab[0] : '';
} else {
this.settings[name] = spec[name].default as string;
}
Expand All @@ -126,59 +128,62 @@ export class InterpreterControls extends ReactiveElement {
return html`
<div class="control-holder">
<div class="control-name">
${(required ? '*':'') + name}
${(required ? '*' : '') + name}
</div>
${this.renderControl(name, spec[name])}
</div>`;
});
}

renderControl(name: string, controlType: LitType) {
if (isLitSubtype(controlType, ['SparseMultilabel', 'MultiFieldMatcher'])) {
if (controlType instanceof SparseMultilabel ||
controlType instanceof MultiFieldMatcher) {
const {vocab} = controlType as LitTypeWithVocab;
// Render checkboxes, with the first item selected.
const renderCheckboxes =
() => controlType.vocab!.map(option => {
const renderCheckboxes = () => vocab.map(option => {
// tslint:disable-next-line:no-any
const change = (e: any) => {
if (e.target.checked) {
(this.settings[name] as string[]).push(option);
} else {
this.settings[name] = (this.settings[name] as string[]).filter(
item => item !== option);
this.settings[name] = (this.settings[name] as string[])
.filter(item => item !== option);
}
};
const isSelected = (this.settings[name] as string[]).indexOf(
option) !== -1;
const isSelected =
(this.settings[name] as string[]).indexOf(option) !== -1;
return html`
<lit-checkbox ?checked=${isSelected} @change=${change}
label=${option} class='checkbox-control'>
</lit-checkbox>
`;
});
return html`<div class='checkbox-holder'>${renderCheckboxes()}</div>`;
} else if (isLitSubtype(controlType, ['CategoryLabel', 'FieldMatcher'])) {
} else if (
controlType instanceof CategoryLabel ||
controlType instanceof FieldMatcher) {
const {vocab} = controlType as LitTypeWithVocab;
// Render a dropdown, with the first item selected.
const updateDropdown = (e: Event) => {
const select = (e.target as HTMLSelectElement);
this.settings[name] = controlType.vocab![select?.selectedIndex || 0];
this.settings[name] = vocab[select?.selectedIndex || 0];
};
const options = controlType.vocab!.map((option, optionIndex) => {
const options = vocab.map((option, optionIndex) => {
return html`
<option value=${optionIndex}>${option}</option>
`;
});
const defaultValue =
controlType.vocab != null && controlType.vocab.length > 0 ?
controlType.vocab[0] : '';
vocab != null && vocab.length > 0 ?
vocab[0] :
'';
return html`<select class="dropdown control" @change=${updateDropdown}
.value=${defaultValue} ?disabled=${controlType.vocab!.length < 2}>
.value=${defaultValue} ?disabled=${vocab.length < 2}>
${options}
</select>`;
} else if (isLitSubtype(controlType, ['Scalar'])) {
} else if (controlType instanceof Scalar) {
// Render a slider.
const step = controlType.step!;
const minVal = controlType.min_val!;
const maxVal = controlType.max_val!;
const {step, min_val: minVal, max_val: maxVal} = controlType;

const updateSettings = (e: Event) => {
const input = (e.target as HTMLInputElement);
Expand Down
5 changes: 3 additions & 2 deletions lit_nlp/client/lib/generated_text_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
*/
import difflib from 'difflib';

import {GeneratedTextCandidate, IndexedInput, Input, LitName, Preds, Spec} from './types';
import {LitName, LitTypeWithParent} from './lit_types';
import {GeneratedTextCandidate, IndexedInput, Input, Preds, Spec} from './types';
import {findSpecKeys, isLitSubtype} from './utils';

// tslint:disable-next-line:no-any difflib does not support Closure imports
Expand Down Expand Up @@ -89,7 +90,7 @@ export function getAllReferenceTexts(
// Search input fields: anything referenced in model's output spec
const inputReferenceKeys = new Set<string>();
for (const outKey of findSpecKeys(outputSpec, GENERATION_TYPES)) {
const parent = outputSpec[outKey].parent;
const {parent} = outputSpec[outKey] as LitTypeWithParent;
if (parent && dataSpec[parent]) {
inputReferenceKeys.add(parent);
}
Expand Down
3 changes: 2 additions & 1 deletion lit_nlp/client/lib/generated_text_utils_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
import 'jasmine';

import {canonicalizeGenerationResults, getAllOutputTexts, getAllReferenceTexts, getFlatTexts, getTextDiff} from './generated_text_utils';
import {LitType} from './lit_types';
import {createLitType} from './lit_types_utils';
import {Input, LitType, Preds, Spec} from './types';
import {Input, Preds, Spec} from './types';

function textSegmentType(): LitType {
return createLitType('TextSegment', {
Expand Down
34 changes: 27 additions & 7 deletions lit_nlp/client/lib/lit_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ function registered(target: any) {
REGISTRY[target.name] = target;
}

const registryKeys = Object.keys(REGISTRY) as ReadonlyArray<string>;
const registryKeys : string[] = Object.keys(REGISTRY);
/**
* The types of all LitTypes in the registry, e.g.
* 'StringLitType' | 'TextSegment' ...
*/
export type LitName = typeof registryKeys[number];

type LitClass = 'LitType';
/** A type alias for the LitType class. */
export type LitClass = 'LitType';
type ScoredTextCandidates = Array<[text: string, score: number|null]>;

/**
Expand All @@ -56,12 +57,26 @@ export class LitType {
// TODO(b/162269499): Replace this with `unknown` after migration.
// tslint:disable-next-line:no-any
readonly default: any|undefined = null;
// If this type is created from an Annotator.
annotated: boolean = false;
// TODO(b/162269499): Update to camel case once we've replaced old LitType.
show_in_data_table: boolean = false;

// TODO(b/162269499): Add isCompatible functionality.
}

/** A type alias for LitType with an align property. */
export type LitTypeWithAlign = LitType&{align: string};

/** A type alias for LitType with a null idx property. */
export type LitTypeWithNullIdx = LitType&{null_idx: number};

/** A type alias for LitType with a parent property. */
export type LitTypeWithParent = LitType&{parent: string};

/** A type alias for LitType with a vocab property. */
export type LitTypeWithVocab = LitType&{vocab: string[]};

/**
* A string LitType.
*/
Expand Down Expand Up @@ -420,6 +435,10 @@ export class SparseMultilabelPreds extends _StringCandidateList {
parent?: string = undefined;
}

// TODO(b/162269499): Rename FieldMatcher to SingleFieldMatcher.
/** A type alias for FieldMatcher or MultiFieldMatcher. */
export type LitTypeOfFieldMatcher = FieldMatcher|MultiFieldMatcher;

/**
* For matching spec fields.
*
Expand Down Expand Up @@ -462,7 +481,8 @@ export class MultiFieldMatcher extends LitType {
/**
* Metadata about a returned salience map.
*/
class _Salience extends LitType {
@registered
export class Salience extends LitType {
/** If the saliency technique is automatically run. */
autorun: boolean = false;
/** If the returned values are signed. */
Expand All @@ -473,14 +493,14 @@ class _Salience extends LitType {
* Metadata about a returned token salience map.
*/
@registered
export class TokenSalience extends _Salience {
export class TokenSalience extends Salience {
}

/**
* Metadata about a returned feature salience map.
*/
@registered
export class FeatureSalience extends _Salience {
export class FeatureSalience extends Salience {
// TODO(b/162269499): Add Typescript dtypes so that we can set default types.
}

Expand All @@ -490,14 +510,14 @@ export class FeatureSalience extends _Salience {
* data:image/jpg;base64,w4J3k1Bfa...
*/
@registered
export class ImageSalience extends _Salience {
export class ImageSalience extends Salience {
}

/**
* Metadata about a returned sequence salience map.
*/
@registered
export class SequenceSalience extends _Salience {
export class SequenceSalience extends Salience {
}

/**
Expand Down
Loading

0 comments on commit 8c6ac11

Please sign in to comment.