Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 125 additions & 30 deletions src/Building.elm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Building exposing (Model, Msg(..), PersistentModel(..), editingButtons, init, initPModel, onEnter, onExit, subscriptions, update, updateArrowPos, updateStatePos, view)

import Bootstrap.Form.InputGroup exposing (Input)
import Browser.Events
import Dict exposing (Dict)
import Environment exposing (Environment)
Expand All @@ -9,7 +10,7 @@ import Json.Decode as D
import Machine exposing (..)
import Mistakes exposing (..)
import Set
import SharedModel exposing (MachineType(..), SharedModel, machineModeButtons)
import SharedModel exposing (SharedModel, machineModeButtons)
import Task
import Tuple exposing (first, second)

Expand All @@ -32,7 +33,7 @@ type PersistentModel
type Msg
= MachineMsg Machine.Msg
| SaveStateName StateID String
| SaveTransitionName TransitionID String
| SaveTransitionName TransitionID ( String, String, String )
| ToggleStart StateID
| ChangeMachine MachineType
| AddState ( Float, Float )
Expand Down Expand Up @@ -131,24 +132,33 @@ update env msg ( model, pModel, sModel ) =

AddingArrowOverOtherState st _ s1 ->
let
newTrans =
case List.head <| Dict.values oldMachine.transitionNames of
oldTransitionNames =
oldMachine.transitionNames

newInputLabel =
case List.head <| Dict.values oldTransitionNames of
Just setchar ->
setchar
setchar.inputLabel

Nothing ->
Set.singleton "x"

newTrans =
{ inputLabel = newInputLabel
, stackTop = "\\epsilon"
, stackPush = [ "\\epsilon" ]
}

newTransID =
case List.maximum <| Dict.keys oldMachine.transitionNames of
case List.maximum <| Dict.keys oldTransitionNames of
Just n ->
n + 1

Nothing ->
0

isValidTransition =
checkTransitionValid newTrans
checkTransitionValid newInputLabel

newDelta : Delta
newDelta =
Expand Down Expand Up @@ -198,16 +208,19 @@ update env msg ( model, pModel, sModel ) =

SelectArrow ( s0, tId, s1 ) ->
let
oldTransName =
newInpLabel =
case Dict.get tId sModel.machine.transitionNames of
Just n ->
renderSet2String n
( renderSet2String n.inputLabel, n.stackTop, showStackPush n.stackPush )

Nothing ->
""
( "", "\\epsilon", "\\epsilon" )

newLab =
newInpLabel
in
if env.holdingShift then
( ( { model | machineState = EditingTransitionLabel ( s0, tId, s1 ) oldTransName }, pModel, sModel ), False, focusInput NoOp )
( ( { model | machineState = EditingTransitionLabel ( s0, tId, s1 ) newLab }, pModel, sModel ), False, focusInput NoOp )

else
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), False, Cmd.none )
Expand Down Expand Up @@ -344,15 +357,32 @@ update env msg ( model, pModel, sModel ) =
in
( ( { model | machineState = newState }, pModel, sModel ), False, Cmd.none )

EditLabel _ lbl ->
EditStateLabel st lbl ->
let
newState =
case model.machineState of
EditingStateLabel st _ ->
EditingStateLabel _ _ ->
EditingStateLabel st lbl

EditingTransitionLabel tr _ ->
EditingTransitionLabel tr lbl
_ ->
model.machineState
in
( ( { model | machineState = newState }, pModel, sModel ), False, Cmd.none )

EditTransitionLabel tr0 lblTy lbl ->
let
newState =
case model.machineState of
EditingTransitionLabel tr ( oldInpLbl, oldStkTop, oldStkPush ) ->
case lblTy of
InputLabel ->
EditingTransitionLabel tr ( lbl, oldStkTop, oldStkPush )

StackTop ->
EditingTransitionLabel tr ( oldInpLbl, lbl, oldStkPush )

StackPush ->
EditingTransitionLabel tr ( oldInpLbl, oldStkTop, lbl )

_ ->
model.machineState
Expand Down Expand Up @@ -388,6 +418,9 @@ update env msg ( model, pModel, sModel ) =
DFA ->
( ( model, pModel, { sModel | machineType = NFA } ), False, Cmd.none )

NPDA ->
( ( model, pModel, { sModel | machineType = NFA } ), False, Cmd.none )

DFA ->
case sModel.machineType of
DFA ->
Expand Down Expand Up @@ -418,6 +451,20 @@ update env msg ( model, pModel, sModel ) =
in
( ( model, pModel, newSModel ), True, Cmd.none )

NPDA ->
( ( model, pModel, { sModel | machineType = DFA } ), False, Cmd.none )

NPDA ->
case sModel.machineType of
DFA ->
( ( model, pModel, { sModel | machineType = NPDA } ), False, Cmd.none )

NFA ->
( ( model, pModel, { sModel | machineType = NPDA } ), False, Cmd.none )

NPDA ->
( ( model, pModel, sModel ), False, Cmd.none )

AddState ( x, y ) ->
case model.machineState of
Regular ->
Expand Down Expand Up @@ -467,16 +514,36 @@ update env msg ( model, pModel, sModel ) =
oldTransitionName =
case Dict.get tId oldMachine.transitionNames of
Just n ->
renderSet2String n
( renderSet2String n.inputLabel, n.stackTop, showStackPush n.stackPush )

_ ->
""
( "", "\\epsilon", "\\epsilon" )
in
if newLbl == oldTransitionName || newLbl == "" then
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), False, Cmd.none )
case sModel.machineType of
DFA ->
if fst newLbl == fst oldTransitionName || fst newLbl == "" then
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), False, Cmd.none )

else
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), True, sendMsg <| SaveTransitionName tId newLbl )
else
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), True, sendMsg <| SaveTransitionName tId newLbl )

NFA ->
if fst newLbl == fst oldTransitionName || fst newLbl == "" then
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), False, Cmd.none )

else
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), True, sendMsg <| SaveTransitionName tId newLbl )

NPDA ->
if
(fst newLbl == fst oldTransitionName || fst newLbl == "")
&& (snd newLbl == snd oldTransitionName || snd newLbl == "\\epsilon")
&& (thd newLbl == thd oldTransitionName || thd newLbl == "\\epsilon")
then
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), False, Cmd.none )

else
( ( { model | machineState = SelectedArrow ( s0, tId, s1 ) }, pModel, sModel ), True, sendMsg <| SaveTransitionName tId newLbl )

SelectedState sId ->
let
Expand All @@ -494,11 +561,11 @@ update env msg ( model, pModel, sModel ) =
let
oldTransName =
case Dict.get tId sModel.machine.transitionNames of
Just n ->
renderSet2String n
Just label ->
( renderSet2String label.inputLabel, label.stackTop, String.concat label.stackPush )

Nothing ->
""
( "", "\\epsilon", "\\epsilon" )
in
( ( { model | machineState = EditingTransitionLabel ( s0, tId, s1 ) oldTransName }, pModel, sModel ), False, focusInput NoOp )

Expand Down Expand Up @@ -633,6 +700,11 @@ update env msg ( model, pModel, sModel ) =
{ oldMachine
| start = Set.singleton sId
}

NPDA ->
{ oldMachine
| start = Set.singleton sId
}
in
( ( model, pModel, { sModel | machine = newMachine } ), True, Cmd.none )

Expand All @@ -643,17 +715,30 @@ update env msg ( model, pModel, sModel ) =
in
( ( { model | machineState = Regular }, pModel, { sModel | machine = newMachine } ), True, Cmd.none )

SaveTransitionName tId newLbl ->
SaveTransitionName tId ( inpLabel, stkTop, stkPush ) ->
let
newTransitions =
parseString2Set newLbl
parseString2Set inpLabel

newLabel =
{ inputLabel = newTransitions
, stackTop =
if stkTop == "" then
"\\epsilon"

else
stkTop
, stackPush =
if stkPush == "" then
[ "\\epsilon" ]

isValidTransition =
checkTransitionValid newTransitions
else
parseStackPush stkPush
}

newMachine =
{ oldMachine
| transitionNames = Dict.insert tId newTransitions oldMachine.transitionNames
| transitionNames = Dict.insert tId newLabel oldMachine.transitionNames
}
in
( ( { model | machineState = Regular }, pModel, { sModel | machine = newMachine } ), True, Cmd.none )
Expand Down Expand Up @@ -740,7 +825,7 @@ view env ( model, pModel, sModel ) =

_ ->
group []
, GraphicSVG.map MachineMsg <| Machine.view env model.machineState sModel.machine Set.empty transMistakes
, GraphicSVG.map MachineMsg <| Machine.view env model.machineState sModel.machineType sModel.machine Set.empty transMistakes
, editingButtons model |> move ( winX / 2 - 30, -winY / 2 + 25 )
, machineModeButtons sModel.machineType winX winY ChangeMachine
]
Expand Down Expand Up @@ -838,3 +923,13 @@ snapIcon =
]
|> move ( 5, -10 )
]


parseStackPush : String -> List String
parseStackPush =
String.split " "


showStackPush : List String -> String
showStackPush =
String.join " "
17 changes: 14 additions & 3 deletions src/Error.elm
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Dict exposing (Dict)
import Environment exposing (Environment)
import GraphicSVG exposing (..)
import Helpers exposing (..)
import Machine exposing (Machine, StateID, TransitionID)
import Machine exposing (Machine, MachineType(..), StateID, TransitionID)
import Mistakes exposing (..)
import Set exposing (Set)
import SharedModel exposing (..)
Expand Down Expand Up @@ -50,6 +50,17 @@ contextHasError err mtype =
_ ->
False

NPDA ->
case err of
EpsTransError ->
True

DuplicateStates _ ->
True

_ ->
False


machineCheck : SharedModel -> Error
machineCheck sModel =
Expand All @@ -61,7 +72,7 @@ machineCheck sModel =
getTransitionMistakes mac

allTransitionLabels =
List.sort <| Set.toList <| Set.remove "\\epsilon" <| List.foldr Set.union Set.empty <| Dict.values mac.transitionNames
List.sort <| Set.toList <| Set.remove "\\epsilon" <| List.foldr Set.union Set.empty <| List.map .inputLabel <| Dict.values mac.transitionNames

catch : Maybe (Set String) -> List String
catch ms =
Expand All @@ -74,7 +85,7 @@ machineCheck sModel =

getTrans : Dict TransitionID StateID -> List String
getTrans d =
(List.concatMap (\e -> Dict.get e mac.transitionNames |> catch) <| Dict.keys d) |> List.sort
(List.concatMap (\e -> Dict.get e mac.transitionNames |> Maybe.map .inputLabel |> catch) <| Dict.keys d) |> List.sort

foldingFunc : ( StateID, Dict TransitionID StateID ) -> Error -> Error
foldingFunc sTuple err =
Expand Down
18 changes: 13 additions & 5 deletions src/Exporting.elm
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ view env ( model, pModel, sModel ) =
|> move ( winX / 6 - 100, -105 )
in
group
[ (GraphicSVG.map MachineMsg <| Machine.view env Regular sModel.machine Set.empty transMistakes) |> move ( -winX / 6, 0 )
[ (GraphicSVG.map MachineMsg <| Machine.view env Regular sModel.machineType sModel.machine Set.empty transMistakes) |> move ( -winX / 6, 0 )
, machineSelected sModel.machineType winX winY
, text "Choose format:"
|> size 20
Expand All @@ -164,7 +164,7 @@ view env ( model, pModel, sModel ) =
group []
, case ( model, pModel.outputType ) of
( ShowingOutput, Tikz ) ->
output (winX / 2) (winY / 2) (generateTikz pModel.time sModel.machine)
output (winX / 2) (winY / 2) (generateTikz pModel.time sModel.machine sModel.machineType)

_ ->
group []
Expand All @@ -181,6 +181,9 @@ machineSelected mtype winX winY =

NFA ->
"NFA"

NPDA ->
"NPDA"
in
text ("Your exported machine type: " ++ mtypeStr)
|> centered
Expand Down Expand Up @@ -296,8 +299,8 @@ output w h txt =
]


generateTikz : Int -> Machine -> String
generateTikz time machine =
generateTikz : Int -> Machine -> MachineType -> String
generateTikz time machine macType =
let
scale =
40
Expand Down Expand Up @@ -361,7 +364,12 @@ generateTikz time machine =
transitionName =
case Dict.get tId machine.transitionNames of
Just n ->
renderSet2String n
case macType of
NPDA ->
renderSet2String n.inputLabel ++ ";" ++ n.stackTop ++ ";" ++ String.join " " n.stackPush

_ ->
renderSet2String n.inputLabel

_ ->
""
Expand Down
Loading