declare Distrib1= [ package(name: f version: 2 depends: [e]) package(name: a version: 1 depends: [b c d]) package(name: b version: 1 depends: [a e]) package(name: b version: 3 depends: [d f]) package(name: c version: 1 depends: nil) package(name:d version: 1 depends: [a]) package(name: f version: 1 depends: [d b]) ] declare fun {Packages D} % takes as argument a distribution D % returns a record such that % - label is 'versions' % - arity is the list of the names of packages in D % - the value of field p is the sorted list of versions of p in D fun {Partition L} % takes as argument a sorted list of pairs % [ P1#V11 ... P1#V1N1 .... PM#VM1 ... PM VMNM ] % returns % [ P1#[V11 ... V1N1] ... PM#[VM1 ... VMNM] ] fun {PartitionAux CurrName CurrList L} case L of nil then [CurrName#CurrList] [] (HN#HV)|R then if CurrName == HN then {PartitionAux CurrName HV|CurrList R} else (CurrName#CurrList)|{PartitionAux HN [HV] R} end end end in case L of nil then nil [] (HN#HV)|R then {PartitionAux HN [HV] R} end end fun {SortPackagesVersions D} % takes as argument a distribution % returns the ordered list of pairs Name#Version of all packages in D {List.sort {List.map D fun {$ P} P.name#P.version end} fun {$ AN#AV BN#BV} AN < BN orelse AN == BN andthen AV > BV end } end in local V = {Partition {SortPackagesVersions D}} R = {Record.make versions {List.map V fun {$ L#_} L end}} in {List.forAll V proc {$ P#VL} R.P = VL end} R end end {Browse {Packages Distrib}} declare fun {Solver Dist Goal} P={Packages Dist} AllNames={Record.arity P} in proc {$ Sol} Sol={Record.make installation AllNames} % initial domains of variables: 0, plus any available version % of the corresponding package {List.forAll AllNames proc {$ PName} Sol.PName :: 0|P.PName end } % goal package must be installed if {List.member Goal AllNames} then Sol.Goal >: 0 else fail end % dependencies {List.forAll Dist proc {$ Pack} Name=Pack.name Version=Pack.version in {List.forAll Pack.depends proc{$ Dep} % package Name in version Version depends on Dep if {List.member Dep AllNames} then {FD.impl Sol.Name=:Version Sol.Dep>:0 1} else Sol.Name\=:Version end end} end} {FD.distribute ff Sol} end end {Browse {SearchAll {Solver Distrib1 f}}}