[mercury-users] type error with existentially typed data structure
Peter Ross
peter.ross at miscrit.be
Fri Sep 7 01:06:39 AEST 2001
With the attached file I get the following type error, and I am a bit
lost as to why it occurs.
petri.m:125: In clause for predicate `petri:bind_env/4':
petri.m:125: in unification of variable `Env'
petri.m:125: and term `BindEnv(Token)':
petri.m:125: type error in argument(s) of higher-order term (with arity 1).
petri.m:125: Functor (BindEnv) has type `((func T) = int)',
petri.m:125: expected type was `((func V_9) = int)';
petri.m:125: argument 1 (Token) has type `T',
petri.m:125: expected type was `V_9'.
For more information, try recompiling with `-E'.
-------------- next part --------------
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
%
% Module: petri
% Author: petdr at miscrit.be
%
% This module represents a petri net.
%
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- module petri.
:- interface.
:- import_module set.
:- type petri.
:- type place(T).
:- type ref(T).
% A new petri net.
:- func init = petri.
:- func new_place(string, set(T)) = place(T).
:- pred insert_place(place(T)::in, ref(place(T))::out,
petri::in, petri::out) is det.
:- func get_place(petri, ref(place(T))) = place(T).
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module int, list, map, set, std_util.
% A petri net.
:- type petri
---> petri(
next_id :: int,
map :: map(int, univ)
).
:- type tokens(T) == set(T).
:- type ref(T) ---> ref(int).
% A single place in the petri net where tokens at this place
% have a type T.
%
:- type place(T)
---> place(
name :: string,
tokens :: tokens(T)
).
% An arc from a place to a transition, where we use bind to bind
% the type T to some environment.
%
:- type arc_place_transition
---> some [T] arc_place_transition(
bind :: bind(T),
from :: ref(place(T))
).
% An arc from a transition to a place where the type of the
% resulting tokens, as computed by the arc expression, is T.
%
:- type arc_transition_place
---> some [T] arc_transition_place(
expression :: expression(T),
to :: ref(place(T))
).
% A transition has a set of incoming arcs which are used to bind
% the environment. This environment is then used by the outgoing
% arcs to decide whether or not to place tokens in the output
% petri net.
%
:- type transition
---> transition(
ingoing :: list(arc_place_transition),
outgoing :: list(arc_transition_place)
).
% An expression is a user defined function which maps the
% enviroment bound by all the incoming arcs to the set of
% tokens which should be placed into the destination place. It
% is possibly because we may not want to create a token at all.
%
% XXX Maybe at some later date we will also probably want to
% paramaterise the environment, so as to avoid more bugs!
%
:- type expression(T) == (func(environment) = set(T)).
:- type bind(T) == (func(T) = environment).
:- type environment == int.
%-----------------------------------------------------------------------------%
init = petri(0, map__init).
new_place(Name, Tokens) = place(Name, Tokens).
insert_place(Place, ref(Id), petri(Id, Map0), petri(Id + 1, Map)) :-
map__det_insert(Map0, Id, univ(Place), Map).
get_place(petri(_NextId, Map), ref(Id)) = Place :-
map__lookup(Map, Id, UnivPlace),
det_univ_to_type(UnivPlace, Place).
%-----------------------------------------------------------------------------%
:- pred bind_env(arc_place_transition::in, environment::out,
petri::in, petri::out) is nondet.
bind_env(ArcPlaceTransition, Env, Petri0, Petri) :-
Place = get_place(Petri0, ArcPlaceTransition ^ from),
BindEnv = ArcPlaceTransition ^ bind,
set__member(Token, Place ^ tokens),
Env = BindEnv(Token),
Petri = Petri0.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
/*
:- inst bind == (func(ground >> ground) = (free >> ground) is det).
:- inst arc_place_transition == bound(arc_place_transition(ground, bind)).
:- inst bind_list == list_skel(pair(ground, bind)).
:- pred find_environment(list(pair(place(T), bind(T)))::in(bind_list),
environment::out) is cc_nondet.
find_environment([], _) :-
error("find_environment called with an empty list []").
find_environment([Place - Bind | Rest], Env) :-
bind(Place, Bind, _Token, InitialEnv),
find_environment_2(Rest, InitialEnv, Env).
:- pred find_environment_2(list(pair(place(T), bind(T)))::in(bind_list),
environment::in, environment::out) is cc_nondet.
find_environment_2([], Env, Env).
find_environment_2([Place - Bind | Rest], InitialEnv, Env) :-
bind(Place, Bind, _Token, BoundEnv),
compatible_environments(InitialEnv, BoundEnv, Env0),
find_environment_2(Rest, Env0, Env).
:- pred compatible_environments(environment::in, environment::in,
environment::out) is semidet.
compatible_environments(Env, Env, Env).
% Given one place and a function to bind a token at that place
% with an enviroment, do it.
:- pred bind(place(T)::in, bind(T)::in, T::out, environment::out) is nondet.
bind(Place, Bind, Token, Env) :-
set__member(Token, Place ^ tokens),
Env = Bind(Token).
*/
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
More information about the users
mailing list