diff --git a/client/src/components/infoview/goals.tsx b/client/src/components/infoview/goals.tsx index fe39515..5a12531 100644 --- a/client/src/components/infoview/goals.tsx +++ b/client/src/components/infoview/goals.tsx @@ -114,6 +114,11 @@ function Hyp({ hyp: h, mvarId }: HypProps) { } +interface GoalProps2 { + goals: InteractiveGoal[] + filter: GoalFilterState +} + interface GoalProps { goal: InteractiveGoal filter: GoalFilterState @@ -121,6 +126,11 @@ interface GoalProps { commandLine: boolean } +interface ProofDisplayProps { + proof: string +} + + /** * Displays the hypotheses, target type and optional case label of a goal according to the * provided `filter`. */ @@ -154,10 +164,10 @@ export const Goal = React.memo((props: GoalProps) => { return
{/* {goal.userName &&
case {goal.userName}
} */} {filter.reverse && goalLi} - { objectHyps.length > 0 && + {! commandLine && objectHyps.length > 0 &&
Objekte:
{objectHyps.map((h, i) => )}
} - { assumptionHyps.length > 0 && + {!commandLine && assumptionHyps.length > 0 &&
Annahmen:
{assumptionHyps.map((h, i) => )}
} {commandLine && commandLineMode && } @@ -166,6 +176,79 @@ export const Goal = React.memo((props: GoalProps) => {
}) +export const MainAssumptions = React.memo((props: GoalProps2) => { + const { goals, filter } = props + + const goal = goals[0] + const filteredList = getFilteredHypotheses(goal.hyps, filter); + const hyps = filter.reverse ? filteredList.slice().reverse() : filteredList; + const locs = React.useContext(LocationsContext) + + const goalLocs = React.useMemo(() => + locs && goal.mvarId ? + { ...locs, subexprTemplate: { mvarId: goal.mvarId, loc: { target: '' }}} : + undefined, + [locs, goal.mvarId]) + + const goalLi =
+
Goal:
+ + + +
+ + const objectHyps = hyps.filter(hyp => !hyp.isAssumption) + const assumptionHyps = hyps.filter(hyp => hyp.isAssumption) + + return
+
Aktuelles Goal
+ {filter.reverse && goalLi} + { objectHyps.length > 0 && +
Objekte:
+ {objectHyps.map((h, i) => )}
} + { assumptionHyps.length > 0 && +
+
Annahmen:
+ {assumptionHyps.map((h, i) => )} +
} +
+}) + +export const OtherGoals = React.memo((props: GoalProps2) => { + const { goals, filter } = props + return <> + {goals && goals.length > 1 && +
+
Weitere Goals
+ {goals.slice(1).map((goal, i) => +
+ + + + +
)} +
} + +}) + +export const ProofDisplay = React.memo((props : ProofDisplayProps) => { + const { proof } = props + const steps = proof.match(/.+/g) + return <> + { steps && +
+
Bisheriger Beweis
+
+
+ {steps.map((s) => +
{s}
+ )} +
+
+
} + +}) + interface GoalsProps { goals: InteractiveGoals filter: GoalFilterState @@ -176,7 +259,7 @@ export function Goals({ goals, filter }: GoalsProps) { return <>No goals } else { return <> - {goals.goals.map((g, i) => )} + {goals.goals.map((g, i) => )} } } diff --git a/client/src/components/infoview/info.tsx b/client/src/components/infoview/info.tsx index 85c6ba5..f157b60 100644 --- a/client/src/components/infoview/info.tsx +++ b/client/src/components/infoview/info.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import type { Location, Diagnostic } from 'vscode-languageserver-protocol'; -import { goalsToString, Goal, FilteredGoals } from './goals' +import { goalsToString, Goal, MainAssumptions, OtherGoals, FilteredGoals, ProofDisplay } from './goals' import { basename, DocumentPosition, RangeHelpers, useEvent, usePausableState, discardMethodNotFound, mapRpcError, useAsyncWithTrigger, PausableProps } from '../../../../node_modules/lean4-infoview/src/infoview/util'; import { ConfigContext, EditorContext, LspDiagnosticsContext, ProgressContext } from '../../../../node_modules/lean4-infoview/src/infoview/contexts'; @@ -17,6 +17,8 @@ import { RpcContext, useRpcSessionAtPos } from '../../../../node_modules/lean4-i import { GoalsLocation, Locations, LocationsContext } from '../../../../node_modules/lean4-infoview/src/infoview/goalLocation'; import { InteractiveCode } from '../../../../node_modules/lean4-infoview/src/infoview/interactiveCode' import { CircularProgress } from '@mui/material'; +import { InputModeContext, MonacoEditorContext } from '../Level' + type InfoStatus = 'updating' | 'error' | 'ready'; type InfoKind = 'cursor' | 'pin'; @@ -84,10 +86,11 @@ interface InfoDisplayContentProps extends PausableProps { error?: string; userWidgets: UserWidgetInstance[]; triggerUpdate: () => Promise; + proof? : string; } const InfoDisplayContent = React.memo((props: InfoDisplayContentProps) => { - const {pos, messages, goals, termGoal, error, userWidgets, triggerUpdate, isPaused, setPaused} = props; + const {pos, messages, goals, termGoal, error, userWidgets, triggerUpdate, isPaused, setPaused, proof} = props; const hasWidget = userWidgets.length > 0; const hasError = !!error; @@ -121,21 +124,26 @@ const InfoDisplayContent = React.memo((props: InfoDisplayContentProps) => { { e.preventDefault(); void triggerUpdate(); }}>{' '}Try again. } -
- { goals && ( - goals.goals.length > 0 - ? <>
Aktuelles Goal
- - :
No Goals
- ) } -
+
+ { goals && goals.goals.length > 0 && <> + + + + } +
+
+ { goals && (goals.goals.length > 0 + ? + :
No Goals
+ )} +
{userWidgets.map(widget => -
- {widget.name} - goal) : []} termGoal={termGoal} - selectedLocations={selectedLocs} widget={widget}/> -
+
+ {widget.name} + goal) : []} + termGoal={termGoal} selectedLocations={selectedLocs} widget={widget}/> +
)} {nothingToShow && ( isPaused ? @@ -203,12 +211,14 @@ function InfoDisplay(props0: InfoDisplayProps & InfoPinnable) { setPaused(isPaused => !isPaused); }); + const editor = React.useContext(MonacoEditorContext) + return ( {/*
*/} {/* */}
- +
{/*
*/}
diff --git a/client/src/components/infoview/infoview.css b/client/src/components/infoview/infoview.css index f90c0d3..c8d072a 100644 --- a/client/src/components/infoview/infoview.css +++ b/client/src/components/infoview/infoview.css @@ -79,3 +79,52 @@ .other-goals .goals-section-title, .other-goals summary, .other-goals summary .font-code { color: #5191d1; } + +.goals-section { + display: flex; + flex-direction: row; +} + +.goals-section div { + flex-grow: 1; +} + +#current-proof, #main-assumptions { + margin-right: 0.8em; +} + +#current-proof, #other-goals { + margin-left: 0.8em; +} + +.proof-display { + max-height: 6em; + overflow-y: auto; + overscroll-behavior-y: contain; + scroll-snap-type: y proximity; + color: #ccc; + +} + +.proof-display div:nth-last-child(4) { + color: #999; +} + +.proof-display div:nth-last-child(3) { + color: #666; +} + +.proof-display div:nth-last-child(2) { + color: #333; +} + +.proof-display div:nth-last-child(1) { + color: #000; + scroll-snap-align: end; +} + +.proof-display-wrapper { + background-color: #f0f0f0; + border-radius: 1em; + padding: 0.6em; +}