Skip to content

Latest commit

History

66 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Geode Loopless

Type Enforced Primitive Recursive Functions (and Sets)

Description

Geode Loopless (GeodeL) is a Domain Specific Language that aims at facilitating the writing and analysis of Primitive Recursive Functions and Sets.

This DSL is embedded in Scala, and aims to use its strong type system to enforce the arity and type of the PrimRec functions and sets, thus ensuring any function or set is really primitive recursive.

Primitive recursive ?

Primitive recursive functions are all the functions on naturals that can be created by combining constants, projections, and the successor function through recursion and composition.

In Scala, this translates to the following (the actual implementation also includes a "stack trace" method debug):

importscala.compiletime.SsealedtraitPrimRecFun[A<:Arity]:typeV=Vector[Nat, A] // sequence of Nats of length Avalarity:A= valueOf[A]
defapply(args: V):Nat// Constants// f(X) = constantsealedcaseclassConst[A<:Arity](valconstant:Nat) extendsPrimRecFun[A]:defapply(args: V) = constant
// Projections// f(X) = x_nsealedcaseclassProj[A<:Arity](valn:Arity) extendsPrimRecFun[A]:defapply(args: V) = args(n)
// Successor// f(x) = Succ(x)caseobjectSuccextendsPrimRecFun[1]:defapply(args: V) =SuccNat(args(0))
// Compostition// f(X) = g(f_1(X), f_2(X), ... , f_ArityG(X)) with X a vector of arity ArityFssealedcaseclassComp[ArityG<:Arity, ArityFs<:Arity](g: PrimRecFun[ArityG], fs: Vector[PrimRecFun[ArityFs], ArityG]) extendsPrimRecFun[ArityFs]:defapply(args: V) = g(fs.map(f => f(args)))
// Recursion// f(X :+ 0) = init(X) with X a vector of arity A-1// f(X :+ S(n)) = step(X :+ n :+ f(X :+ n))sealedcaseclassRec[A<:Arity](base: PrimRecFun[P[A]], step: PrimRecFun[S[A]]) extendsPrimRecFun[A]:defapply(args: V) =valargs_= args.toSPA()
vallast= args_.last
valinit:Vector[Nat, P[A]] = args_.init
last matchcaseZeroNat=> base(init)
caseSuccNat(pred) =>valnArgs= (init :+ pred).toA()
step(nArgs :+ apply(nArgs))

You'll notice each apply method terminates on all inputs, therefore, assuming there are no other constructors for PrimRecFun[A], for any instance fun, fun.apply terminates on all inputs!

We encode in PrimRecSet.scala sets as functions which return either 1 or 0. This construction gives us sets for which set-membership always terminates!

While our set of building blocks seems constraining at first, it is extremely expressive, even allowing a form of pattern matching:

// X match// case _ if X in s0 => f0(X)// case _ if X in s1 => f1(X) // Should only match if X is not in s0, hence the s1 / s0 below (which is equivalent to s1 ∩ s0ᶜ)// ...// case _ => fn+1(X) // where n is NumSetsdefcaseStudy[A<:Arity, NumSets<:Arity](functions: Vector[PrimRecFun[A], S[NumSets]], sets: Vector[PrimRecSet[A], NumSets]):PrimRecFun[A] =//full, s0ᶜ, s0ᶜ ∩ s1ᶜ, s0ᶜ ∩ s1ᶜ ∩ s2ᶜ, ...valrestrictors= sets.scanLeft(full[A]){case (s0, s1) => s0  (s1 ᶜ)}
//s0, s1 \ s0, s2 \ (s0 ∪ s1), ... , full \ (s0 ∪ s1 ∪ ...)valcases= (sets :+ full[A]).zip(restrictors).map{case (set, restrictor) => set  restrictor}
//x in s0 -> f0(x), x in s1 \ s0 -> f1(s), ...valres:PrimRecFun[A] = functions.zip(cases).map{case (f, c) => f * c.chi}.fold(Const(0)){case (acc, f) => acc + f}
UserDefined(s"caseStudy($functions, $sets)", res)

The above also highlights some DSL features, such as +, *, and . The goal is to expand these to include, among other things, a nicer syntax for Rec and caseStudy.

All examples can be found in DerivedFunctions.scala and DerivedSets.scala on branch DerivedFunctions.

Through encoding, it is even possible to have primitive recursive functions on things other than natural numbers. This is one of the next big steps planned for this project.

About

Geode Loopless (GeodeL) is a Domain Specific Language that aims at facilitating the writing and analysis of Primitive Recursive Functions and Sets.

Topics

Resources

Stars

0 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages