@@ -82,15 +82,25 @@ let rec checkChildrenFixedType
8282 | _ -> None)
8383 |> List.choose id
8484 |> function
85- | [] -> ST(( Typed resultType, e), xs)
85+ | [] ->
86+ let childrenDomains = xs |> List.choose ( fun x -> x.SemanticResult.Domain)
87+
88+ match childrenDomains with
89+ | [] -> ST(( Typed resultType, e), xs)
90+ | _ -> ST(( TypedDomain( resultType, childrenDomains), e), xs)
91+
8692 | rs -> ST(( Expecting rs, e), xs)
8793
8894and checkChildrenEqualType ( vars : Map < string , Type >) ( e : Expr , resultType : Type ) ( children : Expr list ) =
8995 let xs = children |> List.map ( extractTypeAndDomain vars)
9096 let types = xs |> List.choose _. SemanticResult.Type |> Set
9197
9298 if Set.count types = 1 then
93- ST(( Typed resultType, e), xs)
99+ let childrenDomains = xs |> List.choose ( fun x -> x.SemanticResult.Domain)
100+
101+ match childrenDomains with
102+ | [] -> ST(( Typed resultType, e), xs)
103+ | _ -> ST(( TypedDomain( resultType, childrenDomains), e), xs)
94104 else
95105 ST(( ExpectingSameType( Set.toList types), e), xs)
96106
@@ -106,8 +116,12 @@ and extractTypeAndDomain (vars: Map<string, Type>) (e: Expr) : SemanticTree =
106116 let r =
107117 checkChildrenFixedType vars ( e, Type.Integer) ( Type.Integer, [ left; right ])
108118
109- let divDomain = Binary( right, Op.Differs, Lit( Int 0 )) |> extractTypeAndDomain vars
110- r.AddDomain divDomain
119+ let zero = Lit( Int 0 )
120+ let diffZero = Binary( right, Op.Differs, zero)
121+ let typedZero = ST(( Typed Type.Integer, zero), [])
122+
123+ let domain = ST(( Typed Type.Boolean, diffZero), [ r.Children[ 1 ]; typedZero ])
124+ r.AddDomain domain
111125 | Op.Equals
112126 | Op.Differs -> checkChildrenEqualType vars ( e, Type.Boolean) [ left; right ]
113127 | Op.AtMost
@@ -400,7 +414,7 @@ let semanticExprToWExpr (e: SemanticTree) : DomainWExpr option =
400414 | None -> None
401415 | Lit( Bool b), [] -> Some( if b then True else False)
402416 | Expr.Var name, [] -> Some( mkBoolVar name)
403- | _ -> failwith $" not implemented : {exprToTree e.Expr}"
417+ | _ -> failwith $" unexpected boolean expression : {exprToTree e.Expr}"
404418 | Some Type.Integer ->
405419 match e.Expr, e.Children with
406420 | Lit( Int i), [] -> Some( Integer i)
@@ -475,3 +489,28 @@ let semanticExprToWExpr (e: SemanticTree) : DomainWExpr option =
475489
476490 let domain = e.SemanticResult.Domain |> Option.bind typedToWExpr
477491 typedToWExpr e |> Option.map ( fun r -> DomainWExpr( domain, r))
492+
493+ // weakest precondition of assignemt
494+ let wpAssignment ( vars : Map < string , Type >, var : string , expr : Expr , postcondition : Expr ) =
495+ let rec loop ( target : Expr ) =
496+ match target with
497+ | Expr.Var name when name.Equals var -> expr
498+ | Binary( l, op, r) -> Binary( loop l, op, loop r)
499+ | Unary( op, r) -> Unary( op, loop r)
500+ | Array xs -> Array( xs |> List.map loop)
501+ | ArrayElem( name, index) -> ArrayElem( name, loop index)
502+ | _ -> target
503+
504+ match extractTypeAndDomain vars postcondition with
505+ | postconditionST when postconditionST.SemanticResult.Type.Equals( Some Type.Boolean) ->
506+ let exprSubstituted = loop postcondition
507+
508+ match extractTypeAndDomain vars exprSubstituted with
509+ | substituted when substituted.SemanticResult.Type.Equals( Some Type.Boolean) ->
510+
511+ match semanticExprToWExpr substituted with
512+ | Some wexpr when wexpr.Domain.IsSome -> Some( wexpr.Domain.Value <&&> wexpr.Expr)
513+ | Some wexpr -> Some( wexpr.Expr :?> Proposition)
514+ | _ -> None
515+ | _ -> None
516+ | _ -> None
0 commit comments