@@ -409,39 +409,20 @@ let semanticExprToWExpr (e: SemanticTree) : DomainWExpr =
409409 let domain = e.SemanticResult.Domain |> Option.map typedToWExpr
410410 DomainWExpr( domain, typedToWExpr e)
411411
412- type StateSpace =
413- | StateSpace of Map < string , Type > * Proposition
414-
415- override this.ToString () : string =
416- let p = this.Proposition.ToString()
417-
418- let vars =
419- this.Vars
420- |> Map.toList
421- |> List.map ( fun ( k , v ) -> $" {k}: {v}" )
422- |> String.concat " \n "
423-
424- $" \n {vars}\n {p}"
425-
426- member this.Proposition =
427- let ( StateSpace ( _ , prop )) = this
428- prop
429-
430- member this.Vars =
431- let ( StateSpace ( vars , _ )) = this
432- vars
412+ let varsToString ( vars : Map < string , Type >) =
413+ vars |> Map.toList |> List.map ( fun ( k , v ) -> $" {k}: {v}" ) |> String.concat " \n "
433414
434415let makeWExpr vars ( expected : Type ) ( expr : Expr ) =
435416 match checkChildrenFixedType vars ( expr, expected) ( expected, [ expr ]) with
436417 | e when e.SemanticResult.Type.IsSome -> Ok( semanticExprToWExpr e)
437418 | e -> Error e.SemanticResult
438419
439- let makeStateSpace vars ( predicate : Expr ) =
420+ let makePredicate vars ( predicate : Expr ) =
440421 match checkChildrenFixedType vars ( predicate, Type.Boolean) ( Type.Boolean, [ predicate ]) with
441422 | pred when pred.SemanticResult.Type.IsSome ->
442423 match semanticExprToWExpr pred with
443- | wexpr when wexpr.Domain.IsSome -> Ok( StateSpace ( vars , wexpr.Domain.Value <&&> wexpr.Expr) )
444- | wexpr -> Ok( StateSpace ( vars , wexpr.Expr :?> Proposition) )
424+ | wexpr when wexpr.Domain.IsSome -> Ok( wexpr.Domain.Value <&&> wexpr.Expr)
425+ | wexpr -> Ok( wexpr.Expr :?> Proposition)
445426 | r -> Error r
446427
447428type Guard =
@@ -456,73 +437,68 @@ type Guard =
456437 body
457438
458439and Statement =
459- | VarDecl of SameTypeDecl list
460440 | Becomes of ( string * DomainWExpr ) list
461441 | If of Guard list
462442 | Do of Guard list
463- | Assert of WExpr
443+ | Assert of Proposition
464444 | Compose of Statement * Statement
465445 | Skip
466446 | Abort
467447
468448// weakest precondition of assignemt
469449// wp.(x := E).P = defined.E ∧ P[x := E]
470- let wpAssignment ( becomes : ( string * DomainWExpr ) list ) ( space : StateSpace ) =
450+ let wpAssignment ( becomes : ( string * DomainWExpr ) list ) ( postcondition : Proposition ) =
471451 let rec substitute ( target : WExpr ) (( var , expr ): string * DomainWExpr ) =
472452 target.TextualSubstitution var expr.Expr
473453
474- let expr = becomes |> List.fold substitute space.Proposition
454+ let expr = becomes |> List.fold substitute postcondition
475455
476456 match becomes |> List.choose ( snd >> _. Domain) with
477- | [] -> StateSpace ( space.Vars , expr :?> Proposition)
457+ | [] -> expr :?> Proposition
478458 | x :: xs ->
479459 let domain = xs |> List.fold ( fun acc x -> acc <&&> x) ( x :?> Proposition)
480- StateSpace ( space.Vars , domain <&&> expr)
460+ domain <&&> expr
481461
482- let wpVarDecls ( xs : SameTypeDecl list ) ( space : StateSpace ) =
483- let addVarType t ( acc : Map < string , Type >) name = Map.add name t acc
484- let addSameType vars t map = vars |> List.fold ( addVarType t) map
485-
486- let newVars =
487- xs |> List.fold ( fun acc ( vars , t ) -> addSameType vars t acc) space.Vars
488-
489- StateSpace( newVars, space.Proposition)
490-
491- let rec wpComposition ( s : Statement , t : Statement ) ( space : StateSpace ) = wpStatement s ( wpStatement t space)
462+ let rec wpComposition ( s : Statement , t : Statement ) ( postcondition : Proposition ) =
463+ wpStatement s ( wpStatement t postcondition)
492464// wp.(if cond0 -> body0 | cond1 -> body1 fi).P = (cond0 ∨ cond1) ∧ (cond0 ⇒ wp.body0.P) ∧ (cond1 ⇒ wp.body1.P)
493- and wpAlternative ( guards : Guard list ) ( space : StateSpace ) =
465+ and wpAlternative ( guards : Guard list ) ( postcondition : Proposition ) =
494466 let conds , bodies =
495467 guards
496- |> List.map ( fun g -> g.Condition, g.Condition ==> ( wpStatement g.Body space ) .Proposition )
468+ |> List.map ( fun g -> g.Condition, g.Condition ==> wpStatement g.Body postcondition )
497469 |> List.unzip
498470
499471 let orConds =
500472 conds.Tail |> List.fold ( fun acc c -> acc <||> c) ( conds.Head :?> Proposition)
501473
502474 let andBodies = bodies.Tail |> List.fold ( fun acc c -> acc <&&> c) bodies.Head
503- StateSpace ( space.Vars , orConds <&&> andBodies)
475+ orConds <&&> andBodies
504476
505477// wlp.(do cond0 → body0 | cond1 → body1 od).P = (cond0 ∧ P ⇒ wp.body0.P) ∧ (cond1 ∧ P ⇒ wp.body1.P)
506- and wlpRepetition ( guards : Guard list ) ( space : StateSpace ) =
478+ and wlpRepetition ( guards : Guard list ) ( postcondition : Proposition ) =
507479 let bodies =
508480 guards
509- |> List.map ( fun g -> g.Condition <&&> space.Proposition ==> ( wpStatement g.Body space ) .Proposition )
481+ |> List.map ( fun g -> g.Condition <&&> postcondition ==> wpStatement g.Body postcondition )
510482
511483 let andBodies = bodies.Tail |> List.fold ( fun acc c -> acc <&&> c) bodies.Head
512- StateSpace ( space.Vars , andBodies)
484+ andBodies
513485
514- and wpStatement ( s : Statement ) ( space : StateSpace ) =
486+ and wpStatement ( s : Statement ) ( postcondition : Proposition ) =
515487 match s with
516- | VarDecl xs -> wpVarDecls xs space
517- | Becomes becomes -> wpAssignment becomes space
518- | Compose( s, t) -> wpComposition ( s, t) space
519- | If guards -> wpAlternative guards space
520- | Do guards -> wlpRepetition guards space
521- | Assert expr -> StateSpace( space.Vars, expr ==> space.Proposition)
522- | Skip -> space // wp.skip.P = P
523- | Abort -> StateSpace( Map.empty, False)
524-
525- let rec astStatementToSemantic ( vars : Map < string , Type >) ( s : AST.Statement ) =
488+ | Becomes becomes -> wpAssignment becomes postcondition
489+ | Compose( s, t) -> wpComposition ( s, t) postcondition
490+ | If guards -> wpAlternative guards postcondition
491+ | Do guards -> wlpRepetition guards postcondition
492+ | Assert expr -> expr ==> postcondition
493+ | Skip -> postcondition // wp.skip.P = P
494+ | Abort -> False
495+
496+ type AstSemanticResult =
497+ | NewVars of Map < string , Type >
498+ | NewStatement of Statement
499+ | FailedSemantic of SemanticResult
500+
501+ let rec astStatementToSemantic ( vars : Map < string , Type >) ( s : AST.Statement ) : AstSemanticResult =
526502 let splitResult ( rs : Result < 'a , 'b > list ) =
527503 let oks , errs = rs |> List.partition Result.isOk
528504
@@ -540,33 +516,36 @@ let rec astStatementToSemantic (vars: Map<string, Type>) (s: AST.Statement) =
540516
541517 oks, errs
542518
543- let guardedBlock ( guards : AST.Guard list ) =
519+ let guardedBlock ( constructor : Guard list -> Statement ) ( guards : AST.Guard list ) =
544520 let oks , errs =
545521 guards
546522 |> List.map ( fun g ->
547- match makeStateSpace vars g.Condition with
523+ match makePredicate vars g.Condition with
548524 | Ok e ->
549525 match astStatementToSemantic vars g.Body with
550- | Ok body -> Ok( Guard( e.Proposition, body))
551- | Error m -> Error m
552- | Error m -> Error m)
526+ | NewStatement body -> Ok( Guard( e, body))
527+ | FailedSemantic m -> Error m
528+ | NewVars _ -> failwith " not implemented"
529+ | Error m -> Error m.SemanticResult)
553530 |> splitResult
554531
555532 match errs with
556- | [] -> Ok oks
557- | errs ->
558- let r = errs |> List.map _. SemanticResult |> MultipleResults
559- Error( ST(( r, Lit( Str " " )), []))
560-
533+ | [] -> constructor oks |> NewStatement
534+ | errs -> errs |> MultipleResults |> FailedSemantic
561535
562536 match s with
563- | AST.VarDecl xs -> Ok( VarDecl xs)
564- | AST.Abort -> Ok Abort
565- | AST.Skip -> Ok Skip
537+ | AST.VarDecl xs ->
538+ let addVarType t ( acc : Map < string , Type >) name = Map.add name t acc
539+ let addSameType vars t map = vars |> List.fold ( addVarType t) map
540+
541+ let newVars = xs |> List.fold ( fun acc ( vars , t ) -> addSameType vars t acc) vars
542+ NewVars newVars
543+ | AST.Abort -> NewStatement Abort
544+ | AST.Skip -> NewStatement Skip
566545 | AST.Assert expr ->
567- match makeStateSpace vars expr with
568- | Ok s -> Ok ( Assert s.Proposition )
569- | Error e -> Error e
546+ match makePredicate vars expr with
547+ | Ok s -> NewStatement ( Assert s)
548+ | Error e -> FailedSemantic e.SemanticResult
570549 | AST.Becomes( vs, exprs) when vs.Length.Equals exprs.Length ->
571550 let oks , errs =
572551 exprs
@@ -578,9 +557,9 @@ let rec astStatementToSemantic (vars: Map<string, Type>) (s: AST.Statement) =
578557 |> splitResult
579558
580559 match errs with
581- | [] -> Ok ( Becomes oks)
582- | [ e ] -> Error ( ST (( e , Lit ( Str " " )), []))
583- | _ -> Error ( ST (( MultipleResults errs, Lit ( Str " " )), []) )
584- | AST.Becomes _ -> Error ( ST (( MalformedAssignment , Lit ( Str " " )), []))
585- | AST.Do guards -> guardedBlock guards |> Result.map Do
586- | AST.If guards -> guardedBlock guards |> Result.map If
560+ | [] -> NewStatement ( Becomes oks)
561+ | [ e ] -> FailedSemantic e
562+ | _ -> FailedSemantic ( MultipleResults errs)
563+ | AST.Becomes _ -> FailedSemantic MalformedAssignment
564+ | AST.Do guards -> guardedBlock Do guards
565+ | AST.If guards -> guardedBlock If guards
0 commit comments