Framex
Maintained by Erdal Turan.
FrameNet is a lexical database organized around semantic frames. Following
Boas, Ruppenhofer, and Baker, a frame has a prose definition, a set of lexical
units that evoke it, and frame elements: the situation-specific participants
and props involved. Annotated corpus sentences show which spans realize those
elements. A lexical unit is one word sense in one frame: for example, hope.v
evokes Desiring.
This concise description follows FrameNet at 25: Results and Applications, §2, rather than inventing a competing terminology.
Framex does not introduce a new semantic theory. FrameNet is the computational-lexicographic application of Frame Semantics, the linguistic theory developed by Charles J. Fillmore in the mid-1970s. Fillmore’s 1975 work introduced the approach and his 1976 article, Frame Semantics and the Nature of Language, gave its classic formulation. The word frame also appeared in related work by other scholars at the time; Fillmore’s distinctive contribution was relating word meanings to the structured situations that they evoke.
Framex is a read-only Elixir query layer for a reviewed FrameNet JSON
artifact. It lets an application ask which frame a word sense evokes, which
roles the frame has, how those roles appear in real sentences, and how frames
relate to one another. It is intended for artifacts produced from FrameNet 1.7
XML, but its runtime does not require Python, XML, or the original corpus.
What FrameNet represents
FrameNet treats meaning as structured background knowledge, not as an isolated
word-to-gloss mapping. Understanding a word that evokes a frame makes the
other parts of that situation available as well. For example, hope.v evokes
the Desiring frame: someone who desires (Experiencer) wants a possible
change or state (Event) to occur. A sentence may state some of those roles,
leave others unexpressed, or realize them in different grammatical forms.
The resource records five connected kinds of evidence:
- A frame is the situation or concept, with a prose definition. Frames can describe events, states, attributes, relations, or entities.
- A lexical unit (LU) is a word sense or multiword expression associated
with one frame, such as
hope.vinDesiring; it has its own definition. - A frame element (FE) is a role or prop in that situation. FEs are marked as core when they help define the frame, or as peripheral or extra-thematic when they provide more general contextual information.
- Valence records the observed grammatical realizations of FEs for an LU: for example, a role expressed as an external noun phrase, a prepositional phrase, or a finite clause.
- Annotated exemplars connect the analysis to real corpus sentences. They identify the target expression and the exact text spans that realize FEs.
Frames are also connected by typed relations. An Inheritance relation means
that a more specific frame inherits structure from a more general one; the
bundled corpus, for example, contains Motion_noise → Motion → Event.
This summary paraphrases Section 2 of Boas, Ruppenhofer, and Baker’s FrameNet at 25: Results and Applications.
Framex requires Elixir 1.18 or newer and uses Elixir's built-in JSON module;
it has no JSON-library dependency.
The catalog is loaded once. Annotation JSON files remain on disk and are read
only when Framex.Annotation.exemplars/2 requests a lexical unit.
Install
def deps do
[{:framex, "~> 0.1.2"}]
end
Open an artifact
{:ok, corpus} = Framex.open("priv/framenet-1.7")
Bundled demo artifact
The Hex package includes a small, real FrameNet 1.7 artifact at
priv/corpora/demo_en_17. It contains the hope.v, purchase.v, and swish.v
lexical units, their selected frames, semantic-type closure, internal frame
relations, and up to twelve annotated exemplars per lexical unit.
with {:ok, corpus} <- Framex.open(Application.app_dir(:framex, "priv/corpora/demo_en_17")),
{:ok, hope} <- Framex.Lu.get(corpus, 6604),
{:ok, examples} <- Framex.Annotation.arrangements(corpus, 6604) do
%{lexical_unit: hope["name"], frame: hope["frame"], first_example: List.first(examples)}
end
In IEx, this returns only the final summary rather than printing the catalog as an intermediate assignment value.
The complete corpus is deliberately not embedded in the Hex package. Use an external artifact path for the full FrameNet dataset.
Fetch a profile or the full corpus
The package includes a small demo_en_17 corpus, so the examples above work
immediately after installing framex. For downloaded data, add
framex_tools and run the Framex Mix task:
mix framex.corpus.fetch --corpus_profile demo_en_17
This downloads the focused profile artifact and extracts it into the consumer
project's priv/corpora directory. To download the complete FrameNet release,
use either equivalent full-corpus spelling:
mix framex.corpus.fetch --full
mix framex.corpus.fetch --corpus_full
After either command, open the extracted corpus with:
{:ok, corpus} = Framex.open("priv/corpora/framenet-1.7-streamed")
For a GitHub development checkout of both repositories, the top-level
framex dependency should use override: true because framex_tools also
declares framex as a dependency.
Three FrameNet-style investigations
The bundled corpus is small, but its records are genuine FrameNet 1.7 data.
These IEx queries correspond to three central uses of FrameNet: describing a
lexical entry, inspecting a corpus annotation, and following the conceptual
network. Start an IEx session with iex -S mix, then open the artifact once:
demo_path = Application.app_dir(:framex, "priv/corpora/demo_en_17")
{:ok, corpus} = Framex.open(demo_path)
1. A lexical entry and its valence
hope.v evokes the Desiring frame. The query returns its conceptually core
roles and the number of annotated syntactic valence patterns. A valence pattern
records how a frame element is expressed, for example as a noun phrase or a
finite clause.
with {:ok, hope} <- Framex.Lu.get(corpus, 6604),
{:ok, desiring} <- Framex.Frame.get(corpus, hope["frame"]),
{:ok, valence} <- Framex.Lu.valence(corpus, 6604) do
%{
lexical_unit: hope["name"],
frame: hope["frame"],
core_roles:
desiring["frame_elements"]
|> Enum.filter(fn element -> element["coreness"] == "Core" end)
|> Enum.map(fn element -> element["name"] end),
valence_patterns: length(valence["patterns"])
}
end
%{
lexical_unit: "hope.v",
frame: "Desiring",
core_roles: ["Experiencer", "Event", "Focal_participant", "Location_of_event"],
valence_patterns: 12
}
2. A corpus sentence with semantic roles
FrameNet does not merely associate a word with a frame: it records which span
of an authentic sentence realizes each frame element. Here, the finite clause
realizes the desired Event.
with {:ok, arrangements} <- Framex.Annotation.arrangements(corpus, 6604) do
List.first(arrangements)
end
%{
target: "hoped",
sentence: "It can be hoped that Spanish Prime Minister ...",
frame_elements: [
%{
name: "Event",
text: "that Spanish Prime Minister ...",
grammatical_function: "Dep",
phrase_type: "Sfin"
}
]
}
3. A frame relation as a conceptual path
Motion_noise is a more specific kind of Motion, which is in turn a kind of
Event. This inheritance path makes the structure of the semantic network
explicit.
Framex.Relation.inheritance_chain(corpus, "Motion_noise")
{:ok, ["Motion_noise", "Motion", "Event"]}
These queries support applications such as explanatory dictionaries, semantic role labeling, language-learning material, and semantic analysis of requirements text. Framex reports corpus evidence; it does not infer facts that are absent from the artifact.
Query modules
| Module | What it queries |
|---|---|
Framex.Corpus | The opened artifact and its lazily read annotation shards. |
Framex.Frame | Frames, their definitions, and their frame elements. |
Framex.Lu | Lexical units, frame membership, search, and valence patterns. |
Framex.Fe | A named frame element within a frame. |
Framex.Annotation | Exemplars, sentences, annotated arrangements, and omitted roles. |
Framex.Relation | Typed frame relations and inheritance paths. |
Framex.SemType | Semantic types attached to frames, frame elements, and lexical units. |
alias Framex.Annotation
alias Framex.Fe
alias Framex.Frame
alias Framex.Lu
alias Framex.Relation
alias Framex.SemType
{:ok, motion} = Frame.get(corpus, "Motion")
units = Lu.for_frame(corpus, "Motion")
{:ok, theme} = Fe.get(corpus, "Motion", "Theme")
{:ok, examples} = Annotation.exemplars(corpus, 123)
{:ok, omitted} = Annotation.omitted_roles(corpus, 123)
{:ok, valence} = Lu.valence(corpus, 123)
relations = Relation.for_frame(corpus, "Motion")
{:ok, chain} = Relation.inheritance_chain(corpus, "Motion")
{:ok, types} = SemType.for_fe(corpus, "Motion", "Theme")
The API is divided into seven modules: Framex.Corpus, Framex.Frame,
Framex.Lu, Framex.Fe, Framex.Annotation, Framex.Relation, and
Framex.SemType.
FrameNet supplies semantic evidence, not application authorization or policy.
See the terminology guide for FrameNet and Framex concepts.