Dynamic scope, F# - dynamic

I'm trying to figure out what this function will evaluate to in F# in a dynamic scope
let y = 3 in
let f g = g 2 + g y in
let y = f (fun x -> x + 4) in
f (fun x -> x + y)
I know that in static scope the answer is 31, but I´m having a problem figuring out what it is in dynamic scope

I assume that this is an academic question, so I will not give a full answer, but try to provide some hints for you to solve this on your own. This is also not really an F# question, because F# uses static scope.
The idea with dynamic scope is essentially that variables will refer to values that were assigned to a given name last during the execution of the program.
In your example, the key thing are the references to the variable y. In Static scope, the reference on line 2 refers to declaration on line 1 and the reference on line 4 refers to definition on line 3:
01: let y = 3 in
02: let f g = g 2 + g y (* ref to line 1 *) in
03: let y = f (fun x -> x + 4) in
04: f (fun x -> x + y (* ref to line 3 *) )
With dynamic scope, the references to y will point to whatever was the last definition of y encountered in the program execution. When running f on line 3, the reference on line 2 will refer to the value defined on line 1. When running the code in line 4, all references to y will refer to value defined on line 3.
To make this easier to explain, I'll rewrite this with two versions of f, f1 and f2 that refer to different variables:
01: let y = 3 in
02a: let f1 g = g 2 + g y (* ref to line 1 *) in
02b: let f2 g = g 2 + g y (* ref to line 3 *) in
03: let y = fa (* last y in scope defined on line 1 *) (fun x -> x + 4) in
04: fb (* last in scope defined on line 3 *) (fun x -> x + y (* ref to line 3 *) )
With this, you should be able to figure out what the result will be.

Related

Why does rewrite not change the type of the expression in this case?

In (*1) one can read next
rewrite prf in expr
If we have prf : x = y, and the required type for expr is some property of x, the rewrite ... in syntax will search for x in the required type of expr and replace it with y.
Now, I have next piece of code (you can copy it to editor and try ctrl-l)
module Test
plusCommZ : y = plus y 0
plusCommZ {y = Z} = Refl
plusCommZ {y = (S k)} = cong $ plusCommZ {y = k}
plusCommS : S (plus y k) = plus y (S k)
plusCommS {y = Z} = Refl
plusCommS {y = (S j)} {k} = let ih = plusCommS {y=j} {k=k} in cong ih
plusComm : (x, y : Nat) -> plus x y = plus y x
plusComm Z y = plusCommZ
plusComm (S k) y =
let
ih = plusComm k y
prfXeqY = sym ih
expr = plusCommS {k=k} {y=y}
-- res = rewrite prfXeqY in expr
in ?hole
below is how hole looks like
- + Test.hole [P]
`-- k : Nat
y : Nat
ih : plus k y = plus y k
prfXeqY : plus y k = plus k y
expr : S (plus y k) = plus y (S k)
-----------------------------------------
Test.hole : S (plus k y) = plus y (S k)
The Question.
It looks to me like expr (from *1) in commented line equals to S (plus y k) = plus y (S k). And prf equals to plus y k = plus k y where x is plus y k and y is plus k y. And rewrite should search for x (namely for plus y k) in expr (namely S (plus y k) = plus y (S k) and should replace x with y (namely with plus k y). And result (res) should be S (plus k y) = plus y (S k).
But this does not work.
I have next answer from idris
rewriting plus y k to plus k y did not change type letty
I could guess rewrite is intended to change type of the resulting expression only. So, it is not working within body of let expression, but only in it's 'in' part. Is this correct?
(*1) http://docs.idris-lang.org/en/latest/proofs/patterns.html
PS. Example from tutorial works fine. I'm just curious to know why the way I've tried to use rewrite didn't work.
Though not stated explicitly stated in the docs, rewrite is syntax-sugary invocation of an Elab tactics script (defined around here).
To why your example does not work: the "required type of expr" isn't found; with just res = rewrite prfXeqY in expr alone, it is unclear, which type res should have (even the unifier could resolve this with let res = … in res.) If you specify the required type, it works as expected:
res = the (S (plus k y) = plus y (S k)) (rewrite prfXeqY in expr)
Unfortunately you did not provide the exact line which makes your code misbehave, somehow you must have done something strange, since with your reasoning you outlined above the code works well:
let
ih = plusComm k y -- plus k y = plus y k
px = plusCommS {k=k} {y=y} -- S (plus y k) = plus y (S k)
in rewrite ih in px

using rewrite in Refl

I am working through Chapter 8 Type Driven Development with Idris, and I have a question about how rewrite interacts with Refl.
This code is shown as an example of how rewrite works on an expression:
myReverse : Vect n elem -> Vect n elem
myReverse [] = []
myReverse {n = S k} (x :: xs)
= let result = myReverse xs ++ [x] in
rewrite plusCommutative 1 k in result
where plusCommutative 1 k will look for any instances of 1 + k and replace it with k + 1.
My question is with this solution to rewriting plusCommutative as part of the exercies as myPlusCommutes with an answer being:
myPlusCommutes : (n : Nat) -> (m : Nat) -> n + m = m + n
myPlusCommutes Z m = rewrite plusZeroRightNeutral m in Refl
myPlusCommutes (S k) m = rewrite myPlusCommutes k m in
rewrite plusSuccRightSucc m k in Refl
I am having trouble with this line:
myPlusCommutes Z m = rewrite plusZeroRightNeutral m in Refl
because from what I can understand by using Refl on its own in that line as such:
myPlusCommutes Z m = Refl
I get this error:
When checking right hand side of myPlusCommutes with expected type
0 + m = m + 0
Type mismatch between
plus m 0 = plus m 0 (Type of Refl)
and
m = plus m 0 (Expected type)
Specifically:
Type mismatch between
plus m 0
and
m
First off, one thing I did not realize is that it appears Refl works from the right side of the = and seeks reflection from that direction.
Next, it would seem that rewriting Refl results in a change from plus m 0 = plus m 0 to m = plus m 0, rewriting from the left but stopping after the first replacement and not going to so far as to replace all instances of plus m 0 with m as I would have expected.
Ultimately, that is my question, why rewriting behaves in such a way. Is rewriting on equality types different and in those cases rewrite only replaces on the left side of the =?
To understand what is going on here we need to take into account the fact that Refl is polymorphic:
λΠ> :set showimplicits
λΠ> :t Refl
Refl : {A : Type} -> {x : A} -> (=) {A = A} {B = A} x x
That means Idris is trying to ascribe a type to the term Refl using information from the context. E.g. Refl in myPlusCommutes Z m = Refl has type plus m 0 = plus m 0. Idris could have picked the LHS of myPlusCommutes' output type and tried to ascribe the type m = m to Refl. Also you can specify the x expression like so : Refl {x = m}.
Now, rewrite works with respect to your current goal, i.e. rewrite Eq replaces all the occurrences of the LHS of Eq with its RHS in your goal, not in some possible typing of Refl.
Let me give you a silly example of using a sequence of rewrites to illustrate what I mean:
foo : (n : Nat) -> n = (n + Z) + Z
foo n =
rewrite sym $ plusAssociative n Z Z in -- 1
rewrite plusZeroRightNeutral n in -- 2
Refl -- 3
We start with goal n = (n + Z) + Z, then
line 1 turns the goal into n = n + (Z + Z) using the law of associativity, then
line 2 turns the current goal n = n + Z (which is definitionally equal to n = n + (Z + Z)) into n = n
line 3 provides a proof term for the current goal (if we wanted to be more explicit, we could have written Refl {x = n} in place of Refl).

Let A,B, C be fad. Consider the equation X = AX + BX + C. Must a solution X be fad?

Let A,B, C be fad. Consider the equation X = AX + BX + C. Must a solution X be fad?
Could you help me solve this question?
fad is a regular language
Assume juxtaposition (AX) means concatenation, and + means union. Then, let A = B = {e} and C = {}, the FAD language containing only the empty string and the empty language, respectively. Then let X be any non-FAD language. Clearly, the equation X = AX + BX + C is true since AX = X, BX = X, and X + X + {} = X.
Here are FAs for {e} and {} (proof, if desired, is left as an exercise):
/-\
--->[q0]-s->q1 | s
\-/
/-\
--->q0 | s
\-/
If juxtaposition and union mean something else, the answer may change. For instance, it's possibly that + means concatenation, but then I don't know what to make of juxtaposition (union? intersection?).

F# Clearly defined mutable variable errors it is not a mutable variable

I have several mutable variables in my code. All of them works except one!
Variable d gets several errors like
learn.fsx(33,25): error FS0027: This value is not mutable. Consider using the mutable keyword, e.g. 'let mutable d = expression'
The problem is that when you look in my code then the variable has clearly been defined as a mutable variable.
I think it is a necessity since the only thing I can think of should cause the problem is that it is something after the variable definition that makes it immutable again.
let seq = [2;2;3;3;5;6]
let exp = [[];[]]
let mutable points = 0
let mutable e = 1
let mutable state = ""
let mutable d = 1
let rec guess (x:int) =
match points with
|100 -> "learned"
|_ -> match seq.[x] with
|d -> match (exp.[((List.length exp)-2)]) with
|[] -> if state = "right" then
exp.[((List.length exp)-1)]#[d]
else
state <- "right"
exp#[[d]]
points <- points + 1
if d = 6 then
d <- 1
else
d <- d + 1
if x = 5 then
(guess 0)
else
(guess (x+1))
|_ -> if state = "right" then
exp.[((List.length exp)-1)]#[d]
else
state <- "right"
exp#[[d]]
if (List.length exp.[((List.length exp)-2)]) >= 2 then
d <- (exp.[((List.length exp)-2)]).[e]
else
if d = 6 then
d <- 1
else
d <- d + 1
e <- e + 1
if x = 5 then
(guess 0)
else
(guess (x+1))
|_ -> points <- points - 1
e <- 1
state <- "wrong"
if d = 6 then
d <- 1
else
d <- d + 1
if x = 5 then
(guess 0)
else
(guess (x+1))
Using d in the match causes that version of d to be used instead of the d defined as a mutable value.
Change the name of the value to something else of use 1 directly.
for example: | d -> match (exp.[((List.length exp)-2)]) can become | 1 -> match (exp.[((List.length exp)-2)])

Tell dependent function in conditional statement branch that condition is true

I have a function with a type signature (x, y : SomeType) -> (cond x y) = True -> SomeType. When I check the condition in if-then-else/case/with statement, how do I pass to the function in a corresponding branch the fact, that condition is true?
You can use DecEq to make this easy:
add : (x, y : Nat) -> x + y < 10 = True -> Nat
add x y _ = x + y
main : IO ()
main =
let x = S Z
in let y = Z
in case decEq (x + y < 10) True of
Yes prf => print (add x y prf)
No _ => putStrLn "x + y is not less than 10"
But you shouldn't.
Using booleans (via = or So) can tell you that something is true, but not why. The why is very important if you want to compose proofs together or break them apart. Imagine if add called a function which needed x + y < 20 - we can't just pass our proof that x + y < 10 = True because Idris knows nothing about the operation, just that it's true.
Instead, you should write the above with a data type which contains why it's true. LTE is a type which does that for less-than comparisons:
add : (x, y : Nat) -> LTE (x + y) 10 -> Nat
add x y _ = x + y
main : IO ()
main =
let x = S Z
in let y = Z
in case isLTE (x + y) 10 of
Yes prf => print (add x y prf)
No _ => putStrLn "x + y is not less than 10"
Now, if add called a function which needed a LTE (x + y) 20 we can write a function to widen the constraint:
widen : a `LTE` b -> (c : Nat) -> a `LTE` (b + c)
widen LTEZero c = LTEZero
widen (LTESucc x) c = LTESucc (widen x c)
This is not something we can easily do with just booleans.