Quick actions

cmd+k|ctrl+k

Navigation

Languages

For Debugging 0+1 != 1

Snippet info

Language

Ats

Visibility

public

Author

steinwaywhw

Created

2017-04-03T16:11:03Z

Updated

2017-04-03T16:14:41Z

staload "sessions.sats"
staload UN = "prelude/SATS/unsafe.sats"

#define C 1
#define S 0


stadef fp (a:t@ype) = lam (p:int->protocol):int->protocol => lam n => pite (n>0, pbrch(C, pmsg(C,a)::p(n+1), pmsg(S,a)::p(n-1)), pmsg(C,a)::p(n+1))
stadef queue (a:t@ype) = pfix2 (fp a)



extern fun empty {a:t@ype} (): chan(C, (queue a) 0)
extern fun elem  {a:t@ype} {n:nat} (chan(C, (queue a) n), a): chan(C, (queue a) (n+1))

implement empty {a} () = let 
	fun server (out: chan(S, (queue a) 0)): void = let 
		val _ = recurse2 {S} {lam (p:int->protocol):int->protocol => lam n => pite (n>0, pbrch(C, pmsg(C,a)::p(n+1), pmsg(S,a)::p(n-1)), pmsg(C,a)::p(n+1))} {0} out 
		val _ = ite_false out
		val x = recv out 
		val tail = empty {a} ()
		val q = elem {a} {0} (tail, x)
	in 	
		cut (q, out)
	end
in 
	create (llam out => server out)
end


implement main0 () = () where {
	val queue = empty {int} ()
	val _ = recurse2 {C} {fp int} {0} queue 
	val _ = ite_false queue 
	val _ = send (queue, 1)

    // This line works
	val _ = recurse2 {C} {fp int} {0+1} queue 
	
	// But this equivalent line doesn't
    // val _ = recurse2 {C} {fp int} {1} queue 
    
    // The constraint is as follows, 
    // eqeq: 
    //   app(app(pfix2; lam(p; lam(n; app(pite; app(>; var(n), 0), app(pbrch; 1, app(pseq; app(pmsg; 1, int), app(var(p); app(+; var(n), 1))), app(pseq; app(pmsg; 0, int), app(var(p); app(-; var(n), 1)))), app(pseq; app(pmsg; 1, int), app(var(p); app(+; var(n), 1))))))); app(+; 0, 1)); 
    //   app(app(pfix2; lam(p; lam(n; app(pite; app(>; var(n), 0), app(pbrch; 1, app(pseq; app(pmsg; 1, int), app(var(p); app(+; var(n), 1))), app(pseq; app(pmsg; 0, int), app(var(p); app(-; var(n), 1)))), app(pseq; app(pmsg; 1, int), app(var(p); app(+; var(n), 1))))))); 1)))
    // 
    // it is saying "0+1 == 1" can not be verified. However, it is obviously true.



	val _ = $UN.cast2void queue

}

////

implement elem {a} (inp, x) = let 
	fun server (out: chan(S,queue(a)), inp: chan(C,queue(a))): void = let 
		val _ = recurse out
		val c = offer out
	in 
		case+ c of 
		| ~Left() => 
			let
				val y = recv out
				val _ = recurse inp
				val _ = choose (inp, Left())
				val _ = send (inp, y) 
			in 
				server (out, inp)
			end
		| ~Right() => 
			let 
				val _ = choose (out, Right())
				val _ = send (out, x)
			in 
				cut (out, inp)
			end
	end
in 
	create (llam out => server (out, inp))
end



INFO