workflow vis-coauthorship-community-evolution
  template: define-unit (authors) -> characterise (full-period co-authorship) ->
            loop(define-unit (windows) -> characterise (per-window co-authorship) ->
                 define-unit (anchor + per-window communities) ->
                 characterise (cross-time overlap/flow) ->
                 contextualise (state projection + flow layout) ->
                 visualise -> abstract (evolution events) -> assess) ->
            generate-knowledge (evolution findings) ->
            characterise (author tenure/centrality/cross-membership) ->
            define-unit (author roles) ->
            visualise (NodeTrix + author timelines) ->
            abstract (stability patterns) -> generate-knowledge (stability findings) ->
            characterise (text features) ->
            loop(build-model (topic model) -> visualise -> assess) ->
            characterise (topic profiles per community-period) ->
            visualise (topic evolution) -> abstract (research foci) ->
            generate-knowledge (foci findings) ->
            characterise (pairwise overlap matrix) -> visualise (overlap matrix) ->
            abstract (overlap patterns) ->
            generate-knowledge (integrated synthesis)
  description: "Visual analytics workflow for identifying and characterising the
    intellectual communities of the IEEE VIS co-authorship network, tracking
    their core stability, membership drift, merge/split/dissolution events, and
    associated research foci across 1990-2024"

# ============================================================================
# INPUT
# ============================================================================

artifact D_papers : entities
  origin: given
  internal structure: elementary
  embedment: {set, time}
  features:
    - id: f_authors
      value structure: list
      value type: reference
      description: "Disambiguated author IDs"
    - id: f_year
      value structure: atomic
      value type: temporal
      description: "Publication year"
    - id: f_title
      value structure: atomic
      value type: text
    - id: f_abstract
      value structure: atomic
      value type: text
    - id: f_keywords
      value structure: list
      value type: text
    - id: f_citations
      value structure: list
      value type: reference
      description: "Citation links (provided but not used in this workflow)"
  description: "3596 IEEE VIS papers (Vis/InfoVis/VAST/SciVis), 1990-2024"

# ============================================================================
# PHASE 0: DEFINE AUTHORS AND FULL-PERIOD CO-AUTHORSHIP NETWORK
# ============================================================================

transform T_define_authors :
  intent: define-unit
  manner: "extract"
  input: D_papers
  output: D_authors
  actor: machine
  description: "Extract distinct disambiguated authors as analysis units"

artifact D_authors : entities
  internal structure: elementary
  embedment: {time, relational structure}
  features:
    - id: f_active_years
      value structure: list
      value type: temporal
      description: "Years in which the author published"
  description: "Distinct disambiguated authors, situated in publication time
    and in the co-authorship network"

transform T_char_coauthor_full :
  intent: characterise
  manner: "define-relations (co-authorship, full period)"
  input: D_authors, D_papers
  output: F_coauthor_full
  actor: machine
  description: "Compute weighted co-authorship relation across the full
    1990-2024 period, edge weight = number of joint papers"

artifact F_coauthor_full : feature(D_authors)
  value structure: relational configuration
  value type: numeric
  representation form: "weighted co-authorship graph, full period (anchor structure)"
  description: "Full-period network used to anchor long-run community structure"

# ============================================================================
# SPECIFICATION: COMMUNITY-DETECTION PARAMETERS
# ============================================================================

artifact S_detection_spec : specification
  origin: given
  representation form: "parameter settings (window length, window step,
    community-detection algorithm and resolution)"
  description: "Initial analyst-defined choices governing temporal windowing
    and community-detection granularity"

# ============================================================================
# PHASE 1-3 (LOOPED): WINDOWING, COMMUNITY DETECTION, CROSS-TIME MATCHING
# ============================================================================

loop L_community_structure:
  purpose: "Refine temporal windowing and community-detection resolution
    until communities are neither too fragmented nor too coarse, and
    community-flow matches (persistence/merge/split/dissolution) are
    plausible given domain knowledge of the VIS community"
  until: "Community partition granularity and cross-time matches are judged
    adequate by the analyst"
  body:

    transform T_partition_windows :
      intent: define-unit
      manner: "time-partitioning with overlapping windows"
      input: D_papers, S_detection_spec
      output: D_windows
      actor: hybrid
      description: "Partition 1990-2024 into overlapping time windows
        (e.g. 5-year windows advancing by 1-2 years)"

    artifact D_windows : entities
      internal structure: episode
      embedment: time
      features:
        - id: f_window_span
          value structure: atomic
          value type: temporal
          description: "Start and end year of the window"
      description: "Overlapping time windows over the publication period"

    transform T_char_window_graphs :
      intent: characterise
      manner: "define-relations (co-authorship, per window)"
      input: D_authors, D_papers, D_windows
      output: F_coauthor_windows
      actor: machine
      description: "Compute weighted co-authorship subgraph restricted to
        authors/papers active within each window"

    artifact F_coauthor_windows : feature(D_windows)
      value structure: relational configuration
      value type: numeric
      representation form: "weighted co-authorship graph per window"
      description: "Sequence of comparable network snapshots"

    transform T_anchor_communities :
      intent: define-unit
      manner: "cluster-by-similarity (graph community detection, full period)"
      input: D_authors, F_coauthor_full, S_detection_spec
      output: D_anchor_communities, F_anchor_membership
      actor: machine
      description: "Detect long-term reference communities from the
        full-period network"

    artifact D_anchor_communities : entities
      internal structure: group/cluster
      embedment: set
      features:
        - id: f_size
          value structure: atomic
          value type: numeric
      description: "Long-run reference communities of collaborating authors"

    artifact F_anchor_membership : feature(D_authors)
      value structure: atomic
      value type: categorical
      description: "Anchor-community label per author"

    transform T_window_communities :
      intent: define-unit
      manner: "cluster-by-similarity (graph community detection, per window)"
      input: D_authors, F_coauthor_windows, S_detection_spec
      output: D_window_communities, F_window_membership
      actor: machine
      description: "Detect communities independently within each windowed
        snapshot, capturing short-lived alliances and emerging groups"

    artifact D_window_communities : entities
      internal structure: group/cluster
      embedment: {set, time}
      features:
        - id: f_size
          value structure: atomic
          value type: numeric
        - id: f_window
          value structure: atomic
          value type: reference
      description: "Per-window communities of collaborating authors"

    artifact F_window_membership : feature(D_authors)
      value structure: atomic
      value type: categorical
      description: "Per-window community label per author (varies by window)"

    transform T_char_overlap :
      intent: characterise
      manner: "define-relations (membership overlap across adjacent windows)"
      input: D_window_communities, F_window_membership
      output: F_community_flow
      actor: machine
      description: "Compute weighted overlap of author membership between
        communities in adjacent/overlapping windows"

    artifact F_community_flow : feature(D_window_communities)
      value structure: relational configuration
      value type: numeric
      representation form: "directed weighted graph linking (community,window)
        pairs by membership overlap"
      description: "Community-flow structure capturing persistence, split,
        merge, emergence, dissolution"

    transform T_project_states :
      intent: contextualise
      manner: "projection-based (community-state embedding)"
      input: D_window_communities, F_community_flow
      output: D_state_space, A_state_projection
      actor: machine
      description: "Embed each (community,window) state in 2D by member/topic
        similarity to reveal stable regimes vs. transient states"

    artifact D_state_space : entities
      internal structure: elementary
      features:
        - id: f_dimensions
          value structure: atomic
          value type: numeric
      description: "Computed 2D projection space for community-window states"

    artifact A_state_projection : arrangement(D_window_communities)
      context: D_state_space
      principle: "similarity-preserving projection of member/topic vectors"
      description: "Layout where proximity indicates persistence across windows"

    transform T_arrange_flow :
      intent: contextualise
      manner: "flow/alluvial arrangement based on temporal order and overlap"
      input: D_window_communities, F_community_flow, D_windows
      output: A_flow_layout
      actor: machine
      description: "Arrange communities along the temporal axis with ribbon
        widths determined by overlap weights"

    artifact A_flow_layout : arrangement(D_window_communities)
      context: D_windows
      principle: "alluvial/stream layout ordered by time window, ribbon width
        by overlap weight"
      description: "Temporal arrangement suitable for visualising merges,
        splits, and dissolutions"

    transform T_vis_evolution :
      intent: visualise
      manner: "coordinated alluvial diagram and projection scatterplot"
      input: A_flow_layout, A_state_projection, F_community_flow
      output: V_evolution
      actor: machine
      description: "Render community-flow as alluvial diagram alongside a 2D
        state-projection scatterplot with trails linking matched states"

    artifact V_evolution : visualisation(A_flow_layout, A_state_projection, F_community_flow)
      layout: "alluvial diagram; 2D projection scatterplot"
      form: "stream ribbons; coloured points with trails"
      encoding: "ribbon width/position from F_community_flow; point position
        from A_state_projection; trails connect matched states across windows"
      description: "Overview for detecting persistent, merging, splitting,
        emerging, and dissolving communities"

    transform T_abstract_events :
      intent: abstract
      manner: "perception-and-interpretation of evolution events"
      input: V_evolution, F_community_flow
      output: P_evolution_events
      actor: human
      description: "Visually identify and classify evolution events
        (persist/split/merge/emerge/dissolve) per community trajectory"

    artifact P_evolution_events : pattern(D_window_communities)
      representation form: "labelled event templates (persist/split/merge/
        emerge/dissolve) per community trajectory"
      description: "Identified structural evolution events"

    transform T_assess_structure :
      intent: assess
      manner: "judge community granularity and match plausibility"
      input: V_evolution, P_evolution_events
      output: K_structure_quality
      actor: human
      description: "Judge whether communities are appropriately resolved and
        whether identified merge/split/dissolution matches are plausible
        given domain knowledge of the VIS community"

    artifact K_structure_quality : knowledge(D_window_communities, P_evolution_events)
      representation form: "quality judgment"
      description: "Assessment of whether resolution/windowing needs adjustment"

    if K_structure_quality indicates refinement needed:
      then:
        transform T_refine_detection_spec :
          intent: generate-knowledge
          manner: "formulate methodological adjustment"
          input: K_structure_quality, S_detection_spec
          output: S_detection_spec_r
          actor: human
          description: "Adjust window size/step, clustering algorithm or
            resolution parameter based on assessment"

        artifact S_detection_spec_r : specification
          representation form: "updated parameter settings"
          description: "Refined temporal-windowing and community-detection
            configuration"

        assign:
          S_detection_spec := S_detection_spec_r
      else:
        exit loop L_community_structure

end loop L_community_structure

transform T_knowledge_evolution :
  intent: generate-knowledge
  manner: "formulate-statements"
  input: P_evolution_events, V_evolution
  output: K_evolution
  actor: human
  description: "Formulate conclusions about the number of distinct long-run
    communities and when/how they merged, split, or dissolved"

artifact K_evolution : knowledge(P_evolution_events, D_window_communities)
  representation form: "statements"
  description: "Conclusions about community count and evolution events"

# ============================================================================
# PHASE 4: CORE STABILITY AND LEADERSHIP
# ============================================================================

transform T_char_author_metrics :
  intent: characterise
  manner: "compute-statistics (tenure, centrality, cross-membership)"
  input: D_authors, F_window_membership, F_coauthor_windows
  output: F_author_metrics
  actor: machine
  description: "Compute per-author tenure (fraction of windows in a given
    community), within-community centrality per window, and count of
    distinct communities occupied over the full period"

artifact F_author_metrics : feature(D_authors)
  value structure: vector
  value type: numeric
  description: "Tenure, centrality, and cross-membership count per author"

transform T_classify_authors :
  intent: define-unit
  manner: "rule-based classification (core / peripheral / boundary-spanning)"
  input: D_authors, F_author_metrics
  output: D_author_roles, F_role_label
  actor: hybrid
  description: "Classify authors into core (high tenure+centrality),
    peripheral/transient, and boundary-spanning (multi-community) roles"

artifact D_author_roles : entities
  internal structure: group/cluster
  embedment: set
  description: "Groups of authors sharing the same structural role"

artifact F_role_label : feature(D_authors)
  value structure: atomic
  value type: categorical
  description: "Assigned role label per author"

transform T_vis_nodetrix :
  intent: visualise
  manner: "node-link/matrix hybrid (NodeTrix)"
  input: D_window_communities, F_coauthor_windows, F_role_label
  output: V_nodetrix
  actor: machine
  description: "For a selected community-period, render the dense
    collaboration core as an adjacency matrix and bridging ties as
    node-link edges"

artifact V_nodetrix : visualisation(D_window_communities, F_coauthor_windows, F_role_label)
  layout: "hybrid node-link and matrix"
  form: "adjacency matrix blocks for dense cores; node-link edges for
    inter-community ties"
  encoding: "matrix cell = intra-core edge weight; node colour = role label;
    external edges = bridging ties"
  description: "Detailed core-periphery/leadership structure of one community"

transform T_vis_author_timeline :
  intent: visualise
  manner: "scarf-plot / event-sequence timeline per author"
  input: D_authors, F_window_membership, D_windows
  output: V_author_timeline
  actor: machine
  description: "Render each author as a track with coloured segments
    indicating community membership per window"

artifact V_author_timeline : visualisation(D_authors, F_window_membership, D_windows)
  layout: "aligned horizontal timelines, one row per author"
  form: "coloured segments"
  encoding: "row = author; horizontal position = time window; colour =
    community membership"
  description: "Author-level view of membership stability and drift"

transform T_abstract_stability :
  intent: abstract
  manner: "perception-and-interpretation of stability/leadership patterns"
  input: V_nodetrix, V_author_timeline, F_author_metrics
  output: P_stability_patterns
  actor: human
  description: "Identify stable cores/leaders per community and members who
    move between or span multiple communities"

artifact P_stability_patterns : pattern(D_authors, D_window_communities)
  representation form: "labelled roles with textual descriptions"
  description: "Core stability, leadership, and drift characterisation"

transform T_knowledge_stability :
  intent: generate-knowledge
  manner: "formulate-statements"
  input: P_stability_patterns
  output: K_stability
  actor: human
  description: "Formulate conclusions about core stability and leadership
    per community"

artifact K_stability : knowledge(P_stability_patterns)
  representation form: "statements"
  description: "Conclusions on which communities have stable cores/leaders
    and which show high turnover"

# ============================================================================
# PHASE 5: RESEARCH FOCI (HUMAN-STEERED TOPIC MODELLING)
# ============================================================================

transform T_char_text_features :
  intent: characterise
  manner: "encode (term-document representation)"
  input: D_papers
  output: F_text_features
  actor: machine
  description: "Build term-document matrix from titles, abstracts, and keywords"

artifact F_text_features : feature(D_papers)
  value structure: matrix
  value type: numeric
  representation form: "term-document matrix"
  description: "Textual representation of papers for topic modelling"

artifact S_topic_spec : specification
  origin: given
  representation form: "parameter settings (number of topics, seed terms)"
  description: "Initial topic-model configuration"

loop L_topic_refinement:
  purpose: "Interactively steer the NMF topic model until topics are
    coherent, non-redundant, and align with recognisable VIS research areas"
  until: "Topics are judged coherent and interpretable"
  body:

    transform T_build_topic_model :
      intent: build-model
      manner: "fit-topic-model (NMF)"
      input: F_text_features, S_topic_spec
      output: M_topic_model
      actor: machine
      description: "Fit NMF topic model using current specification"

    artifact M_topic_model : model(F_text_features)
      model type: "topic model"
      representation form: "matrix factorisation (W,H)"
      description: "NMF-based topic model of the paper corpus"

    transform T_vis_topics :
      intent: visualise
      manner: "topic term/document display"
      input: M_topic_model
      output: V_topics
      actor: machine
      description: "Display top terms per topic and representative documents"

    artifact V_topics : visualisation(M_topic_model)
      layout: "ranked term lists with representative documents"
      form: "ranked term lists, document excerpts"
      encoding: "topic weight -> term rank; document-topic weight ->
        representative document selection"
      description: "Interface for inspecting the current topic decomposition"

    transform T_assess_topics :
      intent: assess
      manner: "judge topic coherence and interpretability"
      input: V_topics
      output: K_topic_quality
      actor: human
      description: "Judge whether topics are coherent, distinct, and align
        with known VIS research areas"

    artifact K_topic_quality : knowledge(M_topic_model)
      representation form: "quality judgment"
      description: "Assessment of topic coherence/redundancy"

    if K_topic_quality indicates refinement needed:
      then:
        transform T_refine_topic_spec :
          intent: generate-knowledge
          manner: "formulate methodological adjustment (merge/split/seed topics)"
          input: K_topic_quality, S_topic_spec
          output: S_topic_spec_r
          actor: human
          description: "Merge redundant topics, split overly broad ones, or
            seed new topics from representative terms/documents"

        artifact S_topic_spec_r : specification
          representation form: "updated parameter settings and seed constraints"
          description: "Refined topic-model configuration"

        assign:
          S_topic_spec := S_topic_spec_r
      else:
        exit loop L_topic_refinement

end loop L_topic_refinement

transform T_char_topic_profiles :
  intent: characterise
  manner: "aggregate (topic-mixture per community-period)"
  input: D_window_communities, M_topic_model, D_papers
  output: F_topic_profiles
  actor: machine
  description: "Aggregate topic-mixtures of papers authored within each
    community-period into a single topic profile"

artifact F_topic_profiles : feature(D_window_communities)
  value structure: vector
  value type: numeric
  description: "Topic-mixture (research-foci) profile per community-window"

transform T_vis_topic_evolution :
  intent: visualise
  manner: "matrix / small-multiples"
  input: F_topic_profiles, D_window_communities, D_windows
  output: V_topic_evolution
  actor: machine
  description: "Visualise topic-profile distributions across communities
    and time"

artifact V_topic_evolution : visualisation(F_topic_profiles, D_window_communities, D_windows)
  layout: "matrix (community x time) / small multiples"
  form: "stacked bars or heatmap cells"
  encoding: "rows = communities; columns = time windows; cell content =
    topic-mixture profile"
  description: "Display of research-foci evolution per community"

transform T_abstract_foci :
  intent: abstract
  manner: "name-patterns"
  input: V_topic_evolution, F_topic_profiles
  output: P_research_foci
  actor: human
  description: "Assign descriptive labels to dominant topics per
    community-period and identify foci shifts over time"

artifact P_research_foci : pattern(D_window_communities)
  representation form: "labelled topic descriptions per community-period"
  description: "Named research foci and their temporal evolution"

transform T_knowledge_foci :
  intent: generate-knowledge
  manner: "formulate-statements"
  input: P_research_foci
  output: K_foci
  actor: human
  description: "Formulate conclusions about each community's main research
    foci and how they evolved"

artifact K_foci : knowledge(P_research_foci)
  representation form: "statements"
  description: "Conclusions about community-specific research foci and
    their evolution"

# ============================================================================
# PHASE 6: CROSS-COMMUNITY MEMBERSHIP OVERLAP
# ============================================================================

transform T_char_overlap_matrix :
  intent: characterise
  manner: "define-relations (pairwise membership overlap within a window)"
  input: D_window_communities, F_window_membership
  output: F_overlap_matrix
  actor: machine
  description: "For each window, compute a pairwise overlap matrix among
    communities based on shared author membership"

artifact F_overlap_matrix : feature(D_window_communities)
  value structure: matrix
  value type: numeric
  representation form: "pairwise community overlap matrix per window"
  description: "Cross-community membership overlap"

transform T_vis_overlap :
  intent: visualise
  manner: "matrix-plot"
  input: F_overlap_matrix
  output: V_overlap
  actor: machine
  description: "Display community x community overlap matrix per window"

artifact V_overlap : visualisation(F_overlap_matrix)
  layout: "matrix grid, selectable per time window"
  form: "heatmap cells"
  encoding: "cell colour intensity = degree of shared authorship"
  description: "Overview for detecting high-overlap community pairs and
    their change over time"

transform T_abstract_overlap :
  intent: abstract
  manner: "find-salient-groups"
  input: V_overlap
  output: P_overlap_patterns
  actor: human
  description: "Identify community pairs with persistently high overlap,
    candidates for merging or loss of distinctiveness"

artifact P_overlap_patterns : pattern(D_window_communities)
  representation form: "ranked list of high-overlap community pairs"
  description: "Salient overlap relationships between communities across time"

# ============================================================================
# FINAL SYNTHESIS
# ============================================================================

transform T_final_synthesis :
  intent: generate-knowledge
  manner: "formulate-statements (integrated synthesis)"
  input: K_evolution, K_stability, K_foci, P_overlap_patterns
  output: K_findings
  actor: human
  description: "Synthesise conclusions across community evolution, core
    stability/leadership, research foci, and cross-community overlap"

artifact K_findings : knowledge(D_window_communities, D_authors)
  representation form: "statements and structured summary"
  description: "Integrated findings: number/identity of major communities,
    core stability and leadership, research foci and their evolution,
    membership overlap and its change over time, and merge/split/
    dissolution events with plausible interpretations"